File: /home/joenio/src/dissertacao-ufba-2016/dataset/PAPERS/inputtracer/valgrind-inputtracer/perf/tinycc.c

1     /*
2      *  TCC - Tiny C Compiler
3      * 
4      *  Copyright (c) 2001-2004 Fabrice Bellard
5      *
6      * This library is free software; you can redistribute it and/or
7      * modify it under the terms of the GNU Lesser General Public
8      * License as published by the Free Software Foundation; either
9      * version 2 of the License, or (at your option) any later version.
10      *
11      * This library is distributed in the hope that it will be useful,
12      * but WITHOUT ANY WARRANTY; without even the implied warranty of
13      * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14      * Lesser General Public License for more details.
15      *
16      * You should have received a copy of the GNU Lesser General Public
17      * License along with this library; if not, write to the Free Software
18      * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19      */
20     #define _GNU_SOURCE
21     
22     // njn: inlined config.h
23     //#include "config.h"
24     //---------------------------------------------------------------------------
25     /* Automatically generated by configure - do not modify */
26     #define CONFIG_TCCDIR "tinycc-extras"
27     #define GCC_MAJOR 3
28     #define HOST_I386 1
29     #define TCC_VERSION "0.9.23"
30     //---------------------------------------------------------------------------
31     
32     // njn: comment out CONFIG_TCCBOOT branch
33     //#ifdef CONFIG_TCCBOOT
34     //
35     //#include "tccboot.h"
36     //#define CONFIG_TCC_STATIC
37     //
38     //#else
39     
40     #include <assert.h>
41     #include <stdlib.h>
42     #include <stdio.h>
43     #include <stdarg.h>
44     #include <string.h>
45     #include <errno.h>
46     #include <math.h>
47     #include <unistd.h>
48     #include <signal.h>
49     #include <fcntl.h>
50     #include <setjmp.h>
51     #include <time.h>
52     #ifdef WIN32
53     #include <sys/timeb.h>
54     #endif
55     #ifndef WIN32
56     #include <sys/time.h>
57     #include <sys/ucontext.h>
58     #endif
59     
60     //#endif /* !CONFIG_TCCBOOT */
61     
62     // Dummy variables used to avoid warnings like these: 
63     // warning: ignoring return value of ‘fwrite’, declared with attribute
64     //    warn_unused_result
65     char* dummy_char_star;
66     size_t dummy_size_t;
67     
68     // njn: inlined elf.h
69     //#include "elf.h"
70     //---------------------------------------------------------------------------
71     /* This file defines standard ELF types, structures, and macros.
72        Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
73        This file is part of the GNU C Library.
74        Contributed by Ian Lance Taylor <ian@cygnus.com>.
75     
76        The GNU C Library is free software; you can redistribute it and/or
77        modify it under the terms of the GNU Library General Public License as
78        published by the Free Software Foundation; either version 2 of the
79        License, or (at your option) any later version.
80     
81        The GNU C Library is distributed in the hope that it will be useful,
82        but WITHOUT ANY WARRANTY; without even the implied warranty of
83        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
84        Library General Public License for more details.
85     
86        You should have received a copy of the GNU Library General Public
87        License along with the GNU C Library; see the file COPYING.LIB.  If not,
88        write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
89        Boston, MA 02111-1307, USA.  */
90     
91     #ifndef _ELF_H
92     #define	_ELF_H 1
93     
94     #ifndef WIN32
95     #include <inttypes.h>
96     #else
97     #ifndef __int8_t_defined
98     #define __int8_t_defined
99     typedef signed char int8_t;
100     typedef	short int int16_t;
101     typedef	int int32_t;
102     typedef long long int int64_t;
103     #endif
104     
105     typedef unsigned char		uint8_t;
106     typedef unsigned short int	uint16_t;
107     typedef unsigned int		uint32_t;
108     typedef unsigned long long int	uint64_t;
109     #endif
110     
111     /* Standard ELF types.  */
112     
113     /* Type for a 16-bit quantity.  */
114     typedef uint16_t Elf32_Half;
115     typedef uint16_t Elf64_Half;
116     
117     /* Types for signed and unsigned 32-bit quantities.  */
118     typedef uint32_t Elf32_Word;
119     typedef	int32_t  Elf32_Sword;
120     typedef uint32_t Elf64_Word;
121     typedef	int32_t  Elf64_Sword;
122     
123     /* Types for signed and unsigned 64-bit quantities.  */
124     typedef uint64_t Elf32_Xword;
125     typedef	int64_t  Elf32_Sxword;
126     typedef uint64_t Elf64_Xword;
127     typedef	int64_t  Elf64_Sxword;
128     
129     /* Type of addresses.  */
130     typedef uint32_t Elf32_Addr;
131     typedef uint64_t Elf64_Addr;
132     
133     /* Type of file offsets.  */
134     typedef uint32_t Elf32_Off;
135     typedef uint64_t Elf64_Off;
136     
137     /* Type for section indices, which are 16-bit quantities.  */
138     typedef uint16_t Elf32_Section;
139     typedef uint16_t Elf64_Section;
140     
141     /* Type of symbol indices.  */
142     typedef uint32_t Elf32_Symndx;
143     typedef uint64_t Elf64_Symndx;
144     
145     
146     /* The ELF file header.  This appears at the start of every ELF file.  */
147     
148     #define EI_NIDENT (16)
149     
150     typedef struct
151     {
152       unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
153       Elf32_Half	e_type;			/* Object file type */
154       Elf32_Half	e_machine;		/* Architecture */
155       Elf32_Word	e_version;		/* Object file version */
156       Elf32_Addr	e_entry;		/* Entry point virtual address */
157       Elf32_Off	e_phoff;		/* Program header table file offset */
158       Elf32_Off	e_shoff;		/* Section header table file offset */
159       Elf32_Word	e_flags;		/* Processor-specific flags */
160       Elf32_Half	e_ehsize;		/* ELF header size in bytes */
161       Elf32_Half	e_phentsize;		/* Program header table entry size */
162       Elf32_Half	e_phnum;		/* Program header table entry count */
163       Elf32_Half	e_shentsize;		/* Section header table entry size */
164       Elf32_Half	e_shnum;		/* Section header table entry count */
165       Elf32_Half	e_shstrndx;		/* Section header string table index */
166     } Elf32_Ehdr;
167     
168     typedef struct
169     {
170       unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
171       Elf64_Half	e_type;			/* Object file type */
172       Elf64_Half	e_machine;		/* Architecture */
173       Elf64_Word	e_version;		/* Object file version */
174       Elf64_Addr	e_entry;		/* Entry point virtual address */
175       Elf64_Off	e_phoff;		/* Program header table file offset */
176       Elf64_Off	e_shoff;		/* Section header table file offset */
177       Elf64_Word	e_flags;		/* Processor-specific flags */
178       Elf64_Half	e_ehsize;		/* ELF header size in bytes */
179       Elf64_Half	e_phentsize;		/* Program header table entry size */
180       Elf64_Half	e_phnum;		/* Program header table entry count */
181       Elf64_Half	e_shentsize;		/* Section header table entry size */
182       Elf64_Half	e_shnum;		/* Section header table entry count */
183       Elf64_Half	e_shstrndx;		/* Section header string table index */
184     } Elf64_Ehdr;
185     
186     /* Fields in the e_ident array.  The EI_* macros are indices into the
187        array.  The macros under each EI_* macro are the values the byte
188        may have.  */
189     
190     #define EI_MAG0		0		/* File identification byte 0 index */
191     #define ELFMAG0		0x7f		/* Magic number byte 0 */
192     
193     #define EI_MAG1		1		/* File identification byte 1 index */
194     #define ELFMAG1		'E'		/* Magic number byte 1 */
195     
196     #define EI_MAG2		2		/* File identification byte 2 index */
197     #define ELFMAG2		'L'		/* Magic number byte 2 */
198     
199     #define EI_MAG3		3		/* File identification byte 3 index */
200     #define ELFMAG3		'F'		/* Magic number byte 3 */
201     
202     /* Conglomeration of the identification bytes, for easy testing as a word.  */
203     #define	ELFMAG		"\177ELF"
204     #define	SELFMAG		4
205     
206     #define EI_CLASS	4		/* File class byte index */
207     #define ELFCLASSNONE	0		/* Invalid class */
208     #define ELFCLASS32	1		/* 32-bit objects */
209     #define ELFCLASS64	2		/* 64-bit objects */
210     #define ELFCLASSNUM	3
211     
212     #define EI_DATA		5		/* Data encoding byte index */
213     #define ELFDATANONE	0		/* Invalid data encoding */
214     #define ELFDATA2LSB	1		/* 2's complement, little endian */
215     #define ELFDATA2MSB	2		/* 2's complement, big endian */
216     #define ELFDATANUM	3
217     
218     #define EI_VERSION	6		/* File version byte index */
219     					/* Value must be EV_CURRENT */
220     
221     #define EI_OSABI	7		/* OS ABI identification */
222     #define ELFOSABI_SYSV		0	/* UNIX System V ABI */
223     #define ELFOSABI_HPUX		1	/* HP-UX */
224     #define ELFOSABI_FREEBSD        9       /* Free BSD */
225     #define ELFOSABI_ARM		97	/* ARM */
226     #define ELFOSABI_STANDALONE	255	/* Standalone (embedded) application */
227     
228     #define EI_ABIVERSION	8		/* ABI version */
229     
230     #define EI_PAD		9		/* Byte index of padding bytes */
231     
232     /* Legal values for e_type (object file type).  */
233     
234     #define ET_NONE		0		/* No file type */
235     #define ET_REL		1		/* Relocatable file */
236     #define ET_EXEC		2		/* Executable file */
237     #define ET_DYN		3		/* Shared object file */
238     #define ET_CORE		4		/* Core file */
239     #define	ET_NUM		5		/* Number of defined types */
240     #define ET_LOPROC	0xff00		/* Processor-specific */
241     #define ET_HIPROC	0xffff		/* Processor-specific */
242     
243     /* Legal values for e_machine (architecture).  */
244     
245     #define EM_NONE		 0		/* No machine */
246     #define EM_M32		 1		/* AT&T WE 32100 */
247     #define EM_SPARC	 2		/* SUN SPARC */
248     #define EM_386		 3		/* Intel 80386 */
249     #define EM_68K		 4		/* Motorola m68k family */
250     #define EM_88K		 5		/* Motorola m88k family */
251     #define EM_486		 6		/* Intel 80486 */
252     #define EM_860		 7		/* Intel 80860 */
253     #define EM_MIPS		 8		/* MIPS R3000 big-endian */
254     #define EM_S370		 9		/* Amdahl */
255     #define EM_MIPS_RS4_BE	10		/* MIPS R4000 big-endian */
256     #define EM_RS6000	11		/* RS6000 */
257     
258     #define EM_PARISC	15		/* HPPA */
259     #define EM_nCUBE	16		/* nCUBE */
260     #define EM_VPP500	17		/* Fujitsu VPP500 */
261     #define EM_SPARC32PLUS	18		/* Sun's "v8plus" */
262     #define EM_960		19		/* Intel 80960 */
263     #define EM_PPC		20		/* PowerPC */
264     
265     #define EM_V800		36		/* NEC V800 series */
266     #define EM_FR20		37		/* Fujitsu FR20 */
267     #define EM_RH32		38		/* TRW RH32 */
268     #define EM_MMA		39		/* Fujitsu MMA */
269     #define EM_ARM		40		/* ARM */
270     #define EM_FAKE_ALPHA	41		/* Digital Alpha */
271     #define EM_SH		42		/* Hitachi SH */
272     #define EM_SPARCV9	43		/* SPARC v9 64-bit */
273     #define EM_TRICORE	44		/* Siemens Tricore */
274     #define EM_ARC		45		/* Argonaut RISC Core */
275     #define EM_H8_300	46		/* Hitachi H8/300 */
276     #define EM_H8_300H	47		/* Hitachi H8/300H */
277     #define EM_H8S		48		/* Hitachi H8S */
278     #define EM_H8_500	49		/* Hitachi H8/500 */
279     #define EM_IA_64	50		/* Intel Merced */
280     #define EM_MIPS_X	51		/* Stanford MIPS-X */
281     #define EM_COLDFIRE	52		/* Motorola Coldfire */
282     #define EM_68HC12	53		/* Motorola M68HC12 */
283     #define EM_NUM		54
284     
285     /* If it is necessary to assign new unofficial EM_* values, please
286        pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
287        chances of collision with official or non-GNU unofficial values.  */
288     
289     #define EM_ALPHA	0x9026
290     #define EM_C60          0x9c60
291     
292     /* Legal values for e_version (version).  */
293     
294     #define EV_NONE		0		/* Invalid ELF version */
295     #define EV_CURRENT	1		/* Current version */
296     #define EV_NUM		2
297     
298     /* Section header.  */
299     
300     typedef struct
301     {
302       Elf32_Word	sh_name;		/* Section name (string tbl index) */
303       Elf32_Word	sh_type;		/* Section type */
304       Elf32_Word	sh_flags;		/* Section flags */
305       Elf32_Addr	sh_addr;		/* Section virtual addr at execution */
306       Elf32_Off	sh_offset;		/* Section file offset */
307       Elf32_Word	sh_size;		/* Section size in bytes */
308       Elf32_Word	sh_link;		/* Link to another section */
309       Elf32_Word	sh_info;		/* Additional section information */
310       Elf32_Word	sh_addralign;		/* Section alignment */
311       Elf32_Word	sh_entsize;		/* Entry size if section holds table */
312     } Elf32_Shdr;
313     
314     typedef struct
315     {
316       Elf64_Word	sh_name;		/* Section name (string tbl index) */
317       Elf64_Word	sh_type;		/* Section type */
318       Elf64_Xword	sh_flags;		/* Section flags */
319       Elf64_Addr	sh_addr;		/* Section virtual addr at execution */
320       Elf64_Off	sh_offset;		/* Section file offset */
321       Elf64_Xword	sh_size;		/* Section size in bytes */
322       Elf64_Word	sh_link;		/* Link to another section */
323       Elf64_Word	sh_info;		/* Additional section information */
324       Elf64_Xword	sh_addralign;		/* Section alignment */
325       Elf64_Xword	sh_entsize;		/* Entry size if section holds table */
326     } Elf64_Shdr;
327     
328     /* Special section indices.  */
329     
330     #define SHN_UNDEF	0		/* Undefined section */
331     #define SHN_LORESERVE	0xff00		/* Start of reserved indices */
332     #define SHN_LOPROC	0xff00		/* Start of processor-specific */
333     #define SHN_HIPROC	0xff1f		/* End of processor-specific */
334     #define SHN_ABS		0xfff1		/* Associated symbol is absolute */
335     #define SHN_COMMON	0xfff2		/* Associated symbol is common */
336     #define SHN_HIRESERVE	0xffff		/* End of reserved indices */
337     
338     /* Legal values for sh_type (section type).  */
339     
340     #define SHT_NULL	 0		/* Section header table entry unused */
341     #define SHT_PROGBITS	 1		/* Program data */
342     #define SHT_SYMTAB	 2		/* Symbol table */
343     #define SHT_STRTAB	 3		/* String table */
344     #define SHT_RELA	 4		/* Relocation entries with addends */
345     #define SHT_HASH	 5		/* Symbol hash table */
346     #define SHT_DYNAMIC	 6		/* Dynamic linking information */
347     #define SHT_NOTE	 7		/* Notes */
348     #define SHT_NOBITS	 8		/* Program space with no data (bss) */
349     #define SHT_REL		 9		/* Relocation entries, no addends */
350     #define SHT_SHLIB	 10		/* Reserved */
351     #define SHT_DYNSYM	 11		/* Dynamic linker symbol table */
352     #define	SHT_NUM		 12		/* Number of defined types.  */
353     #define SHT_LOOS	 0x60000000	/* Start OS-specific */
354     #define SHT_LOSUNW	 0x6ffffffb	/* Sun-specific low bound.  */
355     #define SHT_SUNW_COMDAT  0x6ffffffb
356     #define SHT_SUNW_syminfo 0x6ffffffc
357     #define SHT_GNU_verdef	 0x6ffffffd	/* Version definition section.  */
358     #define SHT_GNU_verneed	 0x6ffffffe	/* Version needs section.  */
359     #define SHT_GNU_versym	 0x6fffffff	/* Version symbol table.  */
360     #define SHT_HISUNW	 0x6fffffff	/* Sun-specific high bound.  */
361     #define SHT_HIOS	 0x6fffffff	/* End OS-specific type */
362     #define SHT_LOPROC	 0x70000000	/* Start of processor-specific */
363     #define SHT_HIPROC	 0x7fffffff	/* End of processor-specific */
364     #define SHT_LOUSER	 0x80000000	/* Start of application-specific */
365     #define SHT_HIUSER	 0x8fffffff	/* End of application-specific */
366     
367     /* Legal values for sh_flags (section flags).  */
368     
369     #define SHF_WRITE	(1 << 0)	/* Writable */
370     #define SHF_ALLOC	(1 << 1)	/* Occupies memory during execution */
371     #define SHF_EXECINSTR	(1 << 2)	/* Executable */
372     #define SHF_MASKPROC	0xf0000000	/* Processor-specific */
373     
374     /* Symbol table entry.  */
375     
376     typedef struct
377     {
378       Elf32_Word	st_name;		/* Symbol name (string tbl index) */
379       Elf32_Addr	st_value;		/* Symbol value */
380       Elf32_Word	st_size;		/* Symbol size */
381       unsigned char	st_info;		/* Symbol type and binding */
382       unsigned char	st_other;		/* No defined meaning, 0 */
383       Elf32_Section	st_shndx;		/* Section index */
384     } Elf32_Sym;
385     
386     typedef struct
387     {
388       Elf64_Word	st_name;		/* Symbol name (string tbl index) */
389       unsigned char	st_info;		/* Symbol type and binding */
390       unsigned char st_other;		/* No defined meaning, 0 */
391       Elf64_Section	st_shndx;		/* Section index */
392       Elf64_Addr	st_value;		/* Symbol value */
393       Elf64_Xword	st_size;		/* Symbol size */
394     } Elf64_Sym;
395     
396     /* The syminfo section if available contains additional information about
397        every dynamic symbol.  */
398     
399     typedef struct
400     {
401       Elf32_Half si_boundto;		/* Direct bindings, symbol bound to */
402       Elf32_Half si_flags;			/* Per symbol flags */
403     } Elf32_Syminfo;
404     
405     typedef struct
406     {
407       Elf64_Half si_boundto;		/* Direct bindings, symbol bound to */
408       Elf64_Half si_flags;			/* Per symbol flags */
409     } Elf64_Syminfo;
410     
411     /* Possible values for si_boundto.  */
412     #define SYMINFO_BT_SELF		0xffff	/* Symbol bound to self */
413     #define SYMINFO_BT_PARENT	0xfffe	/* Symbol bound to parent */
414     #define SYMINFO_BT_LOWRESERVE	0xff00	/* Beginning of reserved entries */
415     
416     /* Possible bitmasks for si_flags.  */
417     #define SYMINFO_FLG_DIRECT	0x0001	/* Direct bound symbol */
418     #define SYMINFO_FLG_PASSTHRU	0x0002	/* Pass-thru symbol for translator */
419     #define SYMINFO_FLG_COPY	0x0004	/* Symbol is a copy-reloc */
420     #define SYMINFO_FLG_LAZYLOAD	0x0008	/* Symbol bound to object to be lazy
421     					   loaded */
422     /* Syminfo version values.  */
423     #define SYMINFO_NONE		0
424     #define SYMINFO_CURRENT		1
425     #define SYMINFO_NUM		2
426     
427     
428     /* Special section index.  */
429     
430     #define SHN_UNDEF	0		/* No section, undefined symbol.  */
431     
432     /* How to extract and insert information held in the st_info field.  */
433     
434     #define ELF32_ST_BIND(val)		(((unsigned char) (val)) >> 4)
435     #define ELF32_ST_TYPE(val)		((val) & 0xf)
436     #define ELF32_ST_INFO(bind, type)	(((bind) << 4) + ((type) & 0xf))
437     
438     /* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field.  */
439     #define ELF64_ST_BIND(val)		ELF32_ST_BIND (val)
440     #define ELF64_ST_TYPE(val)		ELF32_ST_TYPE (val)
441     #define ELF64_ST_INFO(bind, type)	ELF32_ST_INFO ((bind), (type))
442     
443     /* Legal values for ST_BIND subfield of st_info (symbol binding).  */
444     
445     #define STB_LOCAL	0		/* Local symbol */
446     #define STB_GLOBAL	1		/* Global symbol */
447     #define STB_WEAK	2		/* Weak symbol */
448     #define	STB_NUM		3		/* Number of defined types.  */
449     #define STB_LOOS	10		/* Start of OS-specific */
450     #define STB_HIOS	12		/* End of OS-specific */
451     #define STB_LOPROC	13		/* Start of processor-specific */
452     #define STB_HIPROC	15		/* End of processor-specific */
453     
454     /* Legal values for ST_TYPE subfield of st_info (symbol type).  */
455     
456     #define STT_NOTYPE	0		/* Symbol type is unspecified */
457     #define STT_OBJECT	1		/* Symbol is a data object */
458     #define STT_FUNC	2		/* Symbol is a code object */
459     #define STT_SECTION	3		/* Symbol associated with a section */
460     #define STT_FILE	4		/* Symbol's name is file name */
461     #define	STT_NUM		5		/* Number of defined types.  */
462     #define STT_LOOS	11		/* Start of OS-specific */
463     #define STT_HIOS	12		/* End of OS-specific */
464     #define STT_LOPROC	13		/* Start of processor-specific */
465     #define STT_HIPROC	15		/* End of processor-specific */
466     
467     
468     /* Symbol table indices are found in the hash buckets and chain table
469        of a symbol hash table section.  This special index value indicates
470        the end of a chain, meaning no further symbols are found in that bucket.  */
471     
472     #define STN_UNDEF	0		/* End of a chain.  */
473     
474     
475     /* How to extract and insert information held in the st_other field.  */
476     
477     #define ELF32_ST_VISIBILITY(o)	((o) & 0x03)
478     
479     /* For ELF64 the definitions are the same.  */
480     #define ELF64_ST_VISIBILITY(o)	ELF32_ST_VISIBILITY (o)
481     
482     /* Symbol visibility specification encoded in the st_other field.  */
483     #define STV_DEFAULT	0		/* Default symbol visibility rules */
484     #define STV_INTERNAL	1		/* Processor specific hidden class */
485     #define STV_HIDDEN	2		/* Sym unavailable in other modules */
486     #define STV_PROTECTED	3		/* Not preemptible, not exported */
487     
488     
489     /* Relocation table entry without addend (in section of type SHT_REL).  */
490     
491     typedef struct
492     {
493       Elf32_Addr	r_offset;		/* Address */
494       Elf32_Word	r_info;			/* Relocation type and symbol index */
495     } Elf32_Rel;
496     
497     /* I have seen two different definitions of the Elf64_Rel and
498        Elf64_Rela structures, so we'll leave them out until Novell (or
499        whoever) gets their act together.  */
500     /* The following, at least, is used on Sparc v9, MIPS, and Alpha.  */
501     
502     typedef struct
503     {
504       Elf64_Addr	r_offset;		/* Address */
505       Elf64_Xword	r_info;			/* Relocation type and symbol index */
506     } Elf64_Rel;
507     
508     /* Relocation table entry with addend (in section of type SHT_RELA).  */
509     
510     typedef struct
511     {
512       Elf32_Addr	r_offset;		/* Address */
513       Elf32_Word	r_info;			/* Relocation type and symbol index */
514       Elf32_Sword	r_addend;		/* Addend */
515     } Elf32_Rela;
516     
517     typedef struct
518     {
519       Elf64_Addr	r_offset;		/* Address */
520       Elf64_Xword	r_info;			/* Relocation type and symbol index */
521       Elf64_Sxword	r_addend;		/* Addend */
522     } Elf64_Rela;
523     
524     /* How to extract and insert information held in the r_info field.  */
525     
526     #define ELF32_R_SYM(val)		((val) >> 8)
527     #define ELF32_R_TYPE(val)		((val) & 0xff)
528     #define ELF32_R_INFO(sym, type)		(((sym) << 8) + ((type) & 0xff))
529     
530     #define ELF64_R_SYM(i)			((i) >> 32)
531     #define ELF64_R_TYPE(i)			((i) & 0xffffffff)
532     #define ELF64_R_INFO(sym,type)		(((sym) << 32) + (type))
533     
534     /* Program segment header.  */
535     
536     typedef struct
537     {
538       Elf32_Word	p_type;			/* Segment type */
539       Elf32_Off	p_offset;		/* Segment file offset */
540       Elf32_Addr	p_vaddr;		/* Segment virtual address */
541       Elf32_Addr	p_paddr;		/* Segment physical address */
542       Elf32_Word	p_filesz;		/* Segment size in file */
543       Elf32_Word	p_memsz;		/* Segment size in memory */
544       Elf32_Word	p_flags;		/* Segment flags */
545       Elf32_Word	p_align;		/* Segment alignment */
546     } Elf32_Phdr;
547     
548     typedef struct
549     {
550       Elf64_Word	p_type;			/* Segment type */
551       Elf64_Word	p_flags;		/* Segment flags */
552       Elf64_Off	p_offset;		/* Segment file offset */
553       Elf64_Addr	p_vaddr;		/* Segment virtual address */
554       Elf64_Addr	p_paddr;		/* Segment physical address */
555       Elf64_Xword	p_filesz;		/* Segment size in file */
556       Elf64_Xword	p_memsz;		/* Segment size in memory */
557       Elf64_Xword	p_align;		/* Segment alignment */
558     } Elf64_Phdr;
559     
560     /* Legal values for p_type (segment type).  */
561     
562     #define	PT_NULL		0		/* Program header table entry unused */
563     #define PT_LOAD		1		/* Loadable program segment */
564     #define PT_DYNAMIC	2		/* Dynamic linking information */
565     #define PT_INTERP	3		/* Program interpreter */
566     #define PT_NOTE		4		/* Auxiliary information */
567     #define PT_SHLIB	5		/* Reserved */
568     #define PT_PHDR		6		/* Entry for header table itself */
569     #define	PT_NUM		7		/* Number of defined types.  */
570     #define PT_LOOS		0x60000000	/* Start of OS-specific */
571     #define PT_HIOS		0x6fffffff	/* End of OS-specific */
572     #define PT_LOPROC	0x70000000	/* Start of processor-specific */
573     #define PT_HIPROC	0x7fffffff	/* End of processor-specific */
574     
575     /* Legal values for p_flags (segment flags).  */
576     
577     #define PF_X		(1 << 0)	/* Segment is executable */
578     #define PF_W		(1 << 1)	/* Segment is writable */
579     #define PF_R		(1 << 2)	/* Segment is readable */
580     #define PF_MASKPROC	0xf0000000	/* Processor-specific */
581     
582     /* Legal values for note segment descriptor types for core files. */
583     
584     #define NT_PRSTATUS	1		/* Contains copy of prstatus struct */
585     #define NT_FPREGSET	2		/* Contains copy of fpregset struct */
586     #define NT_PRPSINFO	3		/* Contains copy of prpsinfo struct */
587     #define NT_PRXREG	4		/* Contains copy of prxregset struct */
588     #define NT_PLATFORM	5		/* String from sysinfo(SI_PLATFORM) */
589     #define NT_AUXV		6		/* Contains copy of auxv array */
590     #define NT_GWINDOWS	7		/* Contains copy of gwindows struct */
591     #define NT_PSTATUS	10		/* Contains copy of pstatus struct */
592     #define NT_PSINFO	13		/* Contains copy of psinfo struct */
593     #define NT_PRCRED	14		/* Contains copy of prcred struct */
594     #define NT_UTSNAME	15		/* Contains copy of utsname struct */
595     #define NT_LWPSTATUS	16		/* Contains copy of lwpstatus struct */
596     #define NT_LWPSINFO	17		/* Contains copy of lwpinfo struct */
597     
598     /* Legal values for the  note segment descriptor types for object files.  */
599     
600     #define NT_VERSION	1		/* Contains a version string.  */
601     
602     
603     /* Dynamic section entry.  */
604     
605     typedef struct
606     {
607       Elf32_Sword	d_tag;			/* Dynamic entry type */
608       union
609         {
610           Elf32_Word d_val;			/* Integer value */
611           Elf32_Addr d_ptr;			/* Address value */
612         } d_un;
613     } Elf32_Dyn;
614     
615     typedef struct
616     {
617       Elf64_Sxword	d_tag;			/* Dynamic entry type */
618       union
619         {
620           Elf64_Xword d_val;		/* Integer value */
621           Elf64_Addr d_ptr;			/* Address value */
622         } d_un;
623     } Elf64_Dyn;
624     
625     /* Legal values for d_tag (dynamic entry type).  */
626     
627     #define DT_NULL		0		/* Marks end of dynamic section */
628     #define DT_NEEDED	1		/* Name of needed library */
629     #define DT_PLTRELSZ	2		/* Size in bytes of PLT relocs */
630     #define DT_PLTGOT	3		/* Processor defined value */
631     #define DT_HASH		4		/* Address of symbol hash table */
632     #define DT_STRTAB	5		/* Address of string table */
633     #define DT_SYMTAB	6		/* Address of symbol table */
634     #define DT_RELA		7		/* Address of Rela relocs */
635     #define DT_RELASZ	8		/* Total size of Rela relocs */
636     #define DT_RELAENT	9		/* Size of one Rela reloc */
637     #define DT_STRSZ	10		/* Size of string table */
638     #define DT_SYMENT	11		/* Size of one symbol table entry */
639     #define DT_INIT		12		/* Address of init function */
640     #define DT_FINI		13		/* Address of termination function */
641     #define DT_SONAME	14		/* Name of shared object */
642     #define DT_RPATH	15		/* Library search path */
643     #define DT_SYMBOLIC	16		/* Start symbol search here */
644     #define DT_REL		17		/* Address of Rel relocs */
645     #define DT_RELSZ	18		/* Total size of Rel relocs */
646     #define DT_RELENT	19		/* Size of one Rel reloc */
647     #define DT_PLTREL	20		/* Type of reloc in PLT */
648     #define DT_DEBUG	21		/* For debugging; unspecified */
649     #define DT_TEXTREL	22		/* Reloc might modify .text */
650     #define DT_JMPREL	23		/* Address of PLT relocs */
651     #define	DT_BIND_NOW	24		/* Process relocations of object */
652     #define	DT_INIT_ARRAY	25		/* Array with addresses of init fct */
653     #define	DT_FINI_ARRAY	26		/* Array with addresses of fini fct */
654     #define	DT_INIT_ARRAYSZ	27		/* Size in bytes of DT_INIT_ARRAY */
655     #define	DT_FINI_ARRAYSZ	28		/* Size in bytes of DT_FINI_ARRAY */
656     #define	DT_NUM		29		/* Number used */
657     #define DT_LOOS		0x60000000	/* Start of OS-specific */
658     #define DT_HIOS		0x6fffffff	/* End of OS-specific */
659     #define DT_LOPROC	0x70000000	/* Start of processor-specific */
660     #define DT_HIPROC	0x7fffffff	/* End of processor-specific */
661     #define	DT_PROCNUM	DT_MIPS_NUM	/* Most used by any processor */
662     
663     /* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
664        Dyn.d_un.d_val field of the Elf*_Dyn structure.  This follows Sun's
665        approach.  */
666     #define DT_VALRNGLO	0x6ffffd00
667     #define DT_POSFLAG_1	0x6ffffdfd	/* Flags for DT_* entries, effecting
668     					   the following DT_* entry.  */
669     #define DT_SYMINSZ	0x6ffffdfe	/* Size of syminfo table (in bytes) */
670     #define DT_SYMINENT	0x6ffffdff	/* Entry size of syminfo */
671     #define DT_VALRNGHI	0x6ffffdff
672     
673     /* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
674        Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
675     
676        If any adjustment is made to the ELF object after it has been
677        built these entries will need to be adjusted.  */
678     #define DT_ADDRRNGLO	0x6ffffe00
679     #define DT_SYMINFO	0x6ffffeff	/* syminfo table */
680     #define DT_ADDRRNGHI	0x6ffffeff
681     
682     /* The versioning entry types.  The next are defined as part of the
683        GNU extension.  */
684     #define DT_VERSYM	0x6ffffff0
685     
686     /* These were chosen by Sun.  */
687     #define DT_FLAGS_1	0x6ffffffb	/* State flags, see DF_1_* below.  */
688     #define	DT_VERDEF	0x6ffffffc	/* Address of version definition
689     					   table */
690     #define	DT_VERDEFNUM	0x6ffffffd	/* Number of version definitions */
691     #define	DT_VERNEED	0x6ffffffe	/* Address of table with needed
692     					   versions */
693     #define	DT_VERNEEDNUM	0x6fffffff	/* Number of needed versions */
694     #define DT_VERSIONTAGIDX(tag)	(DT_VERNEEDNUM - (tag))	/* Reverse order! */
695     #define DT_VERSIONTAGNUM 16
696     
697     /* Sun added these machine-independent extensions in the "processor-specific"
698        range.  Be compatible.  */
699     #define DT_AUXILIARY    0x7ffffffd      /* Shared object to load before self */
700     #define DT_FILTER       0x7fffffff      /* Shared object to get values from */
701     #define DT_EXTRATAGIDX(tag)	((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
702     #define DT_EXTRANUM	3
703     
704     /* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1
705        entry in the dynamic section.  */
706     #define DF_1_NOW	0x00000001	/* Set RTLD_NOW for this object.  */
707     #define DF_1_GLOBAL	0x00000002	/* Set RTLD_GLOBAL for this object.  */
708     #define DF_1_GROUP	0x00000004	/* Set RTLD_GROUP for this object.  */
709     #define DF_1_NODELETE	0x00000008	/* Set RTLD_NODELETE for this object.*/
710     #define DF_1_LOADFLTR	0x00000010	/* Trigger filtee loading at runtime.*/
711     #define DF_1_INITFIRST	0x00000020	/* Set RTLD_INITFIRST for this object*/
712     #define DF_1_NOOPEN	0x00000040	/* Set RTLD_NOOPEN for this object.  */
713     
714     /* Version definition sections.  */
715     
716     typedef struct
717     {
718       Elf32_Half	vd_version;		/* Version revision */
719       Elf32_Half	vd_flags;		/* Version information */
720       Elf32_Half	vd_ndx;			/* Version Index */
721       Elf32_Half	vd_cnt;			/* Number of associated aux entries */
722       Elf32_Word	vd_hash;		/* Version name hash value */
723       Elf32_Word	vd_aux;			/* Offset in bytes to verdaux array */
724       Elf32_Word	vd_next;		/* Offset in bytes to next verdef
725     					   entry */
726     } Elf32_Verdef;
727     
728     typedef struct
729     {
730       Elf64_Half	vd_version;		/* Version revision */
731       Elf64_Half	vd_flags;		/* Version information */
732       Elf64_Half	vd_ndx;			/* Version Index */
733       Elf64_Half	vd_cnt;			/* Number of associated aux entries */
734       Elf64_Word	vd_hash;		/* Version name hash value */
735       Elf64_Word	vd_aux;			/* Offset in bytes to verdaux array */
736       Elf64_Word	vd_next;		/* Offset in bytes to next verdef
737     					   entry */
738     } Elf64_Verdef;
739     
740     
741     /* Legal values for vd_version (version revision).  */
742     #define VER_DEF_NONE	0		/* No version */
743     #define VER_DEF_CURRENT	1		/* Current version */
744     #define VER_DEF_NUM	2		/* Given version number */
745     
746     /* Legal values for vd_flags (version information flags).  */
747     #define VER_FLG_BASE	0x1		/* Version definition of file itself */
748     #define VER_FLG_WEAK	0x2		/* Weak version identifier */
749     
750     /* Auxialiary version information.  */
751     
752     typedef struct
753     {
754       Elf32_Word	vda_name;		/* Version or dependency names */
755       Elf32_Word	vda_next;		/* Offset in bytes to next verdaux
756     					   entry */
757     } Elf32_Verdaux;
758     
759     typedef struct
760     {
761       Elf64_Word	vda_name;		/* Version or dependency names */
762       Elf64_Word	vda_next;		/* Offset in bytes to next verdaux
763     					   entry */
764     } Elf64_Verdaux;
765     
766     
767     /* Version dependency section.  */
768     
769     typedef struct
770     {
771       Elf32_Half	vn_version;		/* Version of structure */
772       Elf32_Half	vn_cnt;			/* Number of associated aux entries */
773       Elf32_Word	vn_file;		/* Offset of filename for this
774     					   dependency */
775       Elf32_Word	vn_aux;			/* Offset in bytes to vernaux array */
776       Elf32_Word	vn_next;		/* Offset in bytes to next verneed
777     					   entry */
778     } Elf32_Verneed;
779     
780     typedef struct
781     {
782       Elf64_Half	vn_version;		/* Version of structure */
783       Elf64_Half	vn_cnt;			/* Number of associated aux entries */
784       Elf64_Word	vn_file;		/* Offset of filename for this
785     					   dependency */
786       Elf64_Word	vn_aux;			/* Offset in bytes to vernaux array */
787       Elf64_Word	vn_next;		/* Offset in bytes to next verneed
788     					   entry */
789     } Elf64_Verneed;
790     
791     
792     /* Legal values for vn_version (version revision).  */
793     #define VER_NEED_NONE	 0		/* No version */
794     #define VER_NEED_CURRENT 1		/* Current version */
795     #define VER_NEED_NUM	 2		/* Given version number */
796     
797     /* Auxiliary needed version information.  */
798     
799     typedef struct
800     {
801       Elf32_Word	vna_hash;		/* Hash value of dependency name */
802       Elf32_Half	vna_flags;		/* Dependency specific information */
803       Elf32_Half	vna_other;		/* Unused */
804       Elf32_Word	vna_name;		/* Dependency name string offset */
805       Elf32_Word	vna_next;		/* Offset in bytes to next vernaux
806     					   entry */
807     } Elf32_Vernaux;
808     
809     typedef struct
810     {
811       Elf64_Word	vna_hash;		/* Hash value of dependency name */
812       Elf64_Half	vna_flags;		/* Dependency specific information */
813       Elf64_Half	vna_other;		/* Unused */
814       Elf64_Word	vna_name;		/* Dependency name string offset */
815       Elf64_Word	vna_next;		/* Offset in bytes to next vernaux
816     					   entry */
817     } Elf64_Vernaux;
818     
819     
820     /* Legal values for vna_flags.  */
821     #define VER_FLG_WEAK	0x2		/* Weak version identifier */
822     
823     
824     /* Auxiliary vector.  */
825     
826     /* This vector is normally only used by the program interpreter.  The
827        usual definition in an ABI supplement uses the name auxv_t.  The
828        vector is not usually defined in a standard <elf.h> file, but it
829        can't hurt.  We rename it to avoid conflicts.  The sizes of these
830        types are an arrangement between the exec server and the program
831        interpreter, so we don't fully specify them here.  */
832     
833     typedef struct
834     {
835       int a_type;			/* Entry type */
836       union
837         {
838           long int a_val;		/* Integer value */
839           void *a_ptr;		/* Pointer value */
840           void (*a_fcn) (void);	/* Function pointer value */
841         } a_un;
842     } Elf32_auxv_t;
843     
844     typedef struct
845     {
846       long int a_type;		/* Entry type */
847       union
848         {
849           long int a_val;		/* Integer value */
850           void *a_ptr;		/* Pointer value */
851           void (*a_fcn) (void);	/* Function pointer value */
852         } a_un;
853     } Elf64_auxv_t;
854     
855     /* Legal values for a_type (entry type).  */
856     
857     #define AT_NULL		0		/* End of vector */
858     #define AT_IGNORE	1		/* Entry should be ignored */
859     #define AT_EXECFD	2		/* File descriptor of program */
860     #define AT_PHDR		3		/* Program headers for program */
861     #define AT_PHENT	4		/* Size of program header entry */
862     #define AT_PHNUM	5		/* Number of program headers */
863     #define AT_PAGESZ	6		/* System page size */
864     #define AT_BASE		7		/* Base address of interpreter */
865     #define AT_FLAGS	8		/* Flags */
866     #define AT_ENTRY	9		/* Entry point of program */
867     #define AT_NOTELF	10		/* Program is not ELF */
868     #define AT_UID		11		/* Real uid */
869     #define AT_EUID		12		/* Effective uid */
870     #define AT_GID		13		/* Real gid */
871     #define AT_EGID		14		/* Effective gid */
872     
873     /* Some more special a_type values describing the hardware.  */
874     #define AT_PLATFORM	15		/* String identifying platform.  */
875     #define AT_HWCAP	16		/* Machine dependent hints about
876     					   processor capabilities.  */
877     
878     /* This entry gives some information about the FPU initialization
879        performed by the kernel.  */
880     #define AT_FPUCW	17		/* Used FPU control word.  */
881     
882     
883     /* Note section contents.  Each entry in the note section begins with
884        a header of a fixed form.  */
885     
886     typedef struct
887     {
888       Elf32_Word n_namesz;			/* Length of the note's name.  */
889       Elf32_Word n_descsz;			/* Length of the note's descriptor.  */
890       Elf32_Word n_type;			/* Type of the note.  */
891     } Elf32_Nhdr;
892     
893     typedef struct
894     {
895       Elf64_Word n_namesz;			/* Length of the note's name.  */
896       Elf64_Word n_descsz;			/* Length of the note's descriptor.  */
897       Elf64_Word n_type;			/* Type of the note.  */
898     } Elf64_Nhdr;
899     
900     /* Known names of notes.  */
901     
902     /* Solaris entries in the note section have this name.  */
903     #define ELF_NOTE_SOLARIS	"SUNW Solaris"
904     
905     /* Note entries for GNU systems have this name.  */
906     #define ELF_NOTE_GNU		"GNU"
907     
908     
909     /* Defined types of notes for Solaris.  */
910     
911     /* Value of descriptor (one word) is desired pagesize for the binary.  */
912     #define ELF_NOTE_PAGESIZE_HINT	1
913     
914     
915     /* Defined note types for GNU systems.  */
916     
917     /* ABI information.  The descriptor consists of words:
918        word 0: OS descriptor
919        word 1: major version of the ABI
920        word 2: minor version of the ABI
921        word 3: subminor version of the ABI
922     */
923     #define ELF_NOTE_ABI		1
924     
925     /* Known OSes.  These value can appear in word 0 of an ELF_NOTE_ABI
926        note section entry.  */
927     #define ELF_NOTE_OS_LINUX	0
928     #define ELF_NOTE_OS_GNU		1
929     #define ELF_NOTE_OS_SOLARIS2	2
930     
931     
932     /* Motorola 68k specific definitions.  */
933     
934     /* m68k relocs.  */
935     
936     #define R_68K_NONE	0		/* No reloc */
937     #define R_68K_32	1		/* Direct 32 bit  */
938     #define R_68K_16	2		/* Direct 16 bit  */
939     #define R_68K_8		3		/* Direct 8 bit  */
940     #define R_68K_PC32	4		/* PC relative 32 bit */
941     #define R_68K_PC16	5		/* PC relative 16 bit */
942     #define R_68K_PC8	6		/* PC relative 8 bit */
943     #define R_68K_GOT32	7		/* 32 bit PC relative GOT entry */
944     #define R_68K_GOT16	8		/* 16 bit PC relative GOT entry */
945     #define R_68K_GOT8	9		/* 8 bit PC relative GOT entry */
946     #define R_68K_GOT32O	10		/* 32 bit GOT offset */
947     #define R_68K_GOT16O	11		/* 16 bit GOT offset */
948     #define R_68K_GOT8O	12		/* 8 bit GOT offset */
949     #define R_68K_PLT32	13		/* 32 bit PC relative PLT address */
950     #define R_68K_PLT16	14		/* 16 bit PC relative PLT address */
951     #define R_68K_PLT8	15		/* 8 bit PC relative PLT address */
952     #define R_68K_PLT32O	16		/* 32 bit PLT offset */
953     #define R_68K_PLT16O	17		/* 16 bit PLT offset */
954     #define R_68K_PLT8O	18		/* 8 bit PLT offset */
955     #define R_68K_COPY	19		/* Copy symbol at runtime */
956     #define R_68K_GLOB_DAT	20		/* Create GOT entry */
957     #define R_68K_JMP_SLOT	21		/* Create PLT entry */
958     #define R_68K_RELATIVE	22		/* Adjust by program base */
959     /* Keep this the last entry.  */
960     #define R_68K_NUM	23
961     
962     /* Intel 80386 specific definitions.  */
963     
964     /* i386 relocs.  */
965     
966     #define R_386_NONE	0		/* No reloc */
967     #define R_386_32	1		/* Direct 32 bit  */
968     #define R_386_PC32	2		/* PC relative 32 bit */
969     #define R_386_GOT32	3		/* 32 bit GOT entry */
970     #define R_386_PLT32	4		/* 32 bit PLT address */
971     #define R_386_COPY	5		/* Copy symbol at runtime */
972     #define R_386_GLOB_DAT	6		/* Create GOT entry */
973     #define R_386_JMP_SLOT	7		/* Create PLT entry */
974     #define R_386_RELATIVE	8		/* Adjust by program base */
975     #define R_386_GOTOFF	9		/* 32 bit offset to GOT */
976     #define R_386_GOTPC	10		/* 32 bit PC relative offset to GOT */
977     /* Keep this the last entry.  */
978     #define R_386_NUM	11
979     
980     /* SUN SPARC specific definitions.  */
981     
982     /* Values for Elf64_Ehdr.e_flags.  */
983     
984     #define EF_SPARCV9_MM		3
985     #define EF_SPARCV9_TSO		0
986     #define EF_SPARCV9_PSO		1
987     #define EF_SPARCV9_RMO		2
988     #define EF_SPARC_EXT_MASK	0xFFFF00
989     #define EF_SPARC_SUN_US1	0x000200
990     #define EF_SPARC_HAL_R1		0x000400
991     
992     /* SPARC relocs.  */
993     
994     #define R_SPARC_NONE	0		/* No reloc */
995     #define R_SPARC_8	1		/* Direct 8 bit */
996     #define R_SPARC_16	2		/* Direct 16 bit */
997     #define R_SPARC_32	3		/* Direct 32 bit */
998     #define R_SPARC_DISP8	4		/* PC relative 8 bit */
999     #define R_SPARC_DISP16	5		/* PC relative 16 bit */
1000     #define R_SPARC_DISP32	6		/* PC relative 32 bit */
1001     #define R_SPARC_WDISP30	7		/* PC relative 30 bit shifted */
1002     #define R_SPARC_WDISP22	8		/* PC relative 22 bit shifted */
1003     #define R_SPARC_HI22	9		/* High 22 bit */
1004     #define R_SPARC_22	10		/* Direct 22 bit */
1005     #define R_SPARC_13	11		/* Direct 13 bit */
1006     #define R_SPARC_LO10	12		/* Truncated 10 bit */
1007     #define R_SPARC_GOT10	13		/* Truncated 10 bit GOT entry */
1008     #define R_SPARC_GOT13	14		/* 13 bit GOT entry */
1009     #define R_SPARC_GOT22	15		/* 22 bit GOT entry shifted */
1010     #define R_SPARC_PC10	16		/* PC relative 10 bit truncated */
1011     #define R_SPARC_PC22	17		/* PC relative 22 bit shifted */
1012     #define R_SPARC_WPLT30	18		/* 30 bit PC relative PLT address */
1013     #define R_SPARC_COPY	19		/* Copy symbol at runtime */
1014     #define R_SPARC_GLOB_DAT 20		/* Create GOT entry */
1015     #define R_SPARC_JMP_SLOT 21		/* Create PLT entry */
1016     #define R_SPARC_RELATIVE 22		/* Adjust by program base */
1017     #define R_SPARC_UA32	23		/* Direct 32 bit unaligned */
1018     
1019     /* Additional Sparc64 relocs.  */
1020     
1021     #define R_SPARC_PLT32	24		/* Direct 32 bit ref to PLT entry */
1022     #define R_SPARC_HIPLT22	25		/* High 22 bit PLT entry */
1023     #define R_SPARC_LOPLT10	26		/* Truncated 10 bit PLT entry */
1024     #define R_SPARC_PCPLT32	27		/* PC rel 32 bit ref to PLT entry */
1025     #define R_SPARC_PCPLT22	28		/* PC rel high 22 bit PLT entry */
1026     #define R_SPARC_PCPLT10	29		/* PC rel trunc 10 bit PLT entry */
1027     #define R_SPARC_10	30		/* Direct 10 bit */
1028     #define R_SPARC_11	31		/* Direct 11 bit */
1029     #define R_SPARC_64	32		/* Direct 64 bit */
1030     #define R_SPARC_OLO10	33		/* ?? */
1031     #define R_SPARC_HH22	34		/* Top 22 bits of direct 64 bit */
1032     #define R_SPARC_HM10	35		/* High middle 10 bits of ... */
1033     #define R_SPARC_LM22	36		/* Low middle 22 bits of ... */
1034     #define R_SPARC_PC_HH22	37		/* Top 22 bits of pc rel 64 bit */
1035     #define R_SPARC_PC_HM10	38		/* High middle 10 bit of ... */
1036     #define R_SPARC_PC_LM22	39		/* Low miggle 22 bits of ... */
1037     #define R_SPARC_WDISP16	40		/* PC relative 16 bit shifted */
1038     #define R_SPARC_WDISP19	41		/* PC relative 19 bit shifted */
1039     #define R_SPARC_7	43		/* Direct 7 bit */
1040     #define R_SPARC_5	44		/* Direct 5 bit */
1041     #define R_SPARC_6	45		/* Direct 6 bit */
1042     #define R_SPARC_DISP64	46		/* PC relative 64 bit */
1043     #define R_SPARC_PLT64	47		/* Direct 64 bit ref to PLT entry */
1044     #define R_SPARC_HIX22	48		/* High 22 bit complemented */
1045     #define R_SPARC_LOX10	49		/* Truncated 11 bit complemented */
1046     #define R_SPARC_H44	50		/* Direct high 12 of 44 bit */
1047     #define R_SPARC_M44	51		/* Direct mid 22 of 44 bit */
1048     #define R_SPARC_L44	52		/* Direct low 10 of 44 bit */
1049     #define R_SPARC_REGISTER 53		/* Global register usage */
1050     #define R_SPARC_UA64	54		/* Direct 64 bit unaligned */
1051     #define R_SPARC_UA16	55		/* Direct 16 bit unaligned */
1052     /* Keep this the last entry.  */
1053     #define R_SPARC_NUM	56
1054     
1055     /* For Sparc64, legal values for d_tag of Elf64_Dyn.  */
1056     
1057     #define DT_SPARC_REGISTER 0x70000001
1058     #define DT_SPARC_NUM	2
1059     
1060     /* Bits present in AT_HWCAP, primarily for Sparc32.  */
1061     
1062     #define HWCAP_SPARC_FLUSH	1	/* The cpu supports flush insn.  */
1063     #define HWCAP_SPARC_STBAR	2
1064     #define HWCAP_SPARC_SWAP	4
1065     #define HWCAP_SPARC_MULDIV	8
1066     #define HWCAP_SPARC_V9		16	/* The cpu is v9, so v8plus is ok.  */
1067     
1068     /* MIPS R3000 specific definitions.  */
1069     
1070     /* Legal values for e_flags field of Elf32_Ehdr.  */
1071     
1072     #define EF_MIPS_NOREORDER   1		/* A .noreorder directive was used */
1073     #define EF_MIPS_PIC	    2		/* Contains PIC code */
1074     #define EF_MIPS_CPIC	    4		/* Uses PIC calling sequence */
1075     #define EF_MIPS_XGOT	    8
1076     #define EF_MIPS_64BIT_WHIRL 16
1077     #define EF_MIPS_ABI2	    32
1078     #define EF_MIPS_ABI_ON32    64
1079     #define EF_MIPS_ARCH	    0xf0000000	/* MIPS architecture level */
1080     
1081     /* Legal values for MIPS architecture level.  */
1082     
1083     #define EF_MIPS_ARCH_1	    0x00000000	/* -mips1 code.  */
1084     #define EF_MIPS_ARCH_2	    0x10000000	/* -mips2 code.  */
1085     #define EF_MIPS_ARCH_3	    0x20000000	/* -mips3 code.  */
1086     #define EF_MIPS_ARCH_4	    0x30000000	/* -mips4 code.  */
1087     #define EF_MIPS_ARCH_5	    0x40000000	/* -mips5 code.  */
1088     
1089     /* The following are non-official names and should not be used.  */
1090     
1091     #define E_MIPS_ARCH_1	  0x00000000	/* -mips1 code.  */
1092     #define E_MIPS_ARCH_2	  0x10000000	/* -mips2 code.  */
1093     #define E_MIPS_ARCH_3	  0x20000000	/* -mips3 code.  */
1094     #define E_MIPS_ARCH_4	  0x30000000	/* -mips4 code.  */
1095     #define E_MIPS_ARCH_5	  0x40000000	/* -mips5 code.  */
1096     
1097     /* Special section indices.  */
1098     
1099     #define SHN_MIPS_ACOMMON 0xff00		/* Allocated common symbols */
1100     #define SHN_MIPS_TEXT	 0xff01		/* Allocated test symbols.  */
1101     #define SHN_MIPS_DATA	 0xff02		/* Allocated data symbols.  */
1102     #define SHN_MIPS_SCOMMON 0xff03		/* Small common symbols */
1103     #define SHN_MIPS_SUNDEFINED 0xff04	/* Small undefined symbols */
1104     
1105     /* Legal values for sh_type field of Elf32_Shdr.  */
1106     
1107     #define SHT_MIPS_LIBLIST       0x70000000 /* Shared objects used in link */
1108     #define SHT_MIPS_MSYM	       0x70000001
1109     #define SHT_MIPS_CONFLICT      0x70000002 /* Conflicting symbols */
1110     #define SHT_MIPS_GPTAB	       0x70000003 /* Global data area sizes */
1111     #define SHT_MIPS_UCODE	       0x70000004 /* Reserved for SGI/MIPS compilers */
1112     #define SHT_MIPS_DEBUG	       0x70000005 /* MIPS ECOFF debugging information*/
1113     #define SHT_MIPS_REGINFO       0x70000006 /* Register usage information */
1114     #define SHT_MIPS_PACKAGE       0x70000007
1115     #define SHT_MIPS_PACKSYM       0x70000008
1116     #define SHT_MIPS_RELD	       0x70000009
1117     #define SHT_MIPS_IFACE         0x7000000b
1118     #define SHT_MIPS_CONTENT       0x7000000c
1119     #define SHT_MIPS_OPTIONS       0x7000000d /* Miscellaneous options.  */
1120     #define SHT_MIPS_SHDR	       0x70000010
1121     #define SHT_MIPS_FDESC	       0x70000011
1122     #define SHT_MIPS_EXTSYM	       0x70000012
1123     #define SHT_MIPS_DENSE	       0x70000013
1124     #define SHT_MIPS_PDESC	       0x70000014
1125     #define SHT_MIPS_LOCSYM	       0x70000015
1126     #define SHT_MIPS_AUXSYM	       0x70000016
1127     #define SHT_MIPS_OPTSYM	       0x70000017
1128     #define SHT_MIPS_LOCSTR	       0x70000018
1129     #define SHT_MIPS_LINE	       0x70000019
1130     #define SHT_MIPS_RFDESC	       0x7000001a
1131     #define SHT_MIPS_DELTASYM      0x7000001b
1132     #define SHT_MIPS_DELTAINST     0x7000001c
1133     #define SHT_MIPS_DELTACLASS    0x7000001d
1134     #define SHT_MIPS_DWARF         0x7000001e /* DWARF debugging information.  */
1135     #define SHT_MIPS_DELTADECL     0x7000001f
1136     #define SHT_MIPS_SYMBOL_LIB    0x70000020
1137     #define SHT_MIPS_EVENTS	       0x70000021 /* Event section.  */
1138     #define SHT_MIPS_TRANSLATE     0x70000022
1139     #define SHT_MIPS_PIXIE	       0x70000023
1140     #define SHT_MIPS_XLATE	       0x70000024
1141     #define SHT_MIPS_XLATE_DEBUG   0x70000025
1142     #define SHT_MIPS_WHIRL	       0x70000026
1143     #define SHT_MIPS_EH_REGION     0x70000027
1144     #define SHT_MIPS_XLATE_OLD     0x70000028
1145     #define SHT_MIPS_PDR_EXCEPTION 0x70000029
1146     
1147     /* Legal values for sh_flags field of Elf32_Shdr.  */
1148     
1149     #define SHF_MIPS_GPREL	 0x10000000	/* Must be part of global data area */
1150     #define SHF_MIPS_MERGE	 0x20000000
1151     #define SHF_MIPS_ADDR	 0x40000000
1152     #define SHF_MIPS_STRINGS 0x80000000
1153     #define SHF_MIPS_NOSTRIP 0x08000000
1154     #define SHF_MIPS_LOCAL	 0x04000000
1155     #define SHF_MIPS_NAMES	 0x02000000
1156     #define SHF_MIPS_NODUPE	 0x01000000
1157     
1158     
1159     /* Symbol tables.  */
1160     
1161     /* MIPS specific values for `st_other'.  */
1162     #define STO_MIPS_DEFAULT		0x0
1163     #define STO_MIPS_INTERNAL		0x1
1164     #define STO_MIPS_HIDDEN			0x2
1165     #define STO_MIPS_PROTECTED		0x3
1166     #define STO_MIPS_SC_ALIGN_UNUSED	0xff
1167     
1168     /* MIPS specific values for `st_info'.  */
1169     #define STB_MIPS_SPLIT_COMMON		13
1170     
1171     /* Entries found in sections of type SHT_MIPS_GPTAB.  */
1172     
1173     typedef union
1174     {
1175       struct
1176         {
1177           Elf32_Word gt_current_g_value;	/* -G value used for compilation */
1178           Elf32_Word gt_unused;		/* Not used */
1179         } gt_header;			/* First entry in section */
1180       struct
1181         {
1182           Elf32_Word gt_g_value;		/* If this value were used for -G */
1183           Elf32_Word gt_bytes;		/* This many bytes would be used */
1184         } gt_entry;				/* Subsequent entries in section */
1185     } Elf32_gptab;
1186     
1187     /* Entry found in sections of type SHT_MIPS_REGINFO.  */
1188     
1189     typedef struct
1190     {
1191       Elf32_Word	ri_gprmask;		/* General registers used */
1192       Elf32_Word	ri_cprmask[4];		/* Coprocessor registers used */
1193       Elf32_Sword	ri_gp_value;		/* $gp register value */
1194     } Elf32_RegInfo;
1195     
1196     /* Entries found in sections of type SHT_MIPS_OPTIONS.  */
1197     
1198     typedef struct
1199     {
1200       unsigned char kind;		/* Determines interpretation of the
1201     				   variable part of descriptor.  */
1202       unsigned char size;		/* Size of descriptor, including header.  */
1203       Elf32_Section section;	/* Section header index of section affected,
1204     				   0 for global options.  */
1205       Elf32_Word info;		/* Kind-specific information.  */
1206     } Elf_Options;
1207     
1208     /* Values for `kind' field in Elf_Options.  */
1209     
1210     #define ODK_NULL	0	/* Undefined.  */
1211     #define ODK_REGINFO	1	/* Register usage information.  */
1212     #define ODK_EXCEPTIONS	2	/* Exception processing options.  */
1213     #define ODK_PAD		3	/* Section padding options.  */
1214     #define ODK_HWPATCH	4	/* Hardware workarounds performed */
1215     #define ODK_FILL	5	/* record the fill value used by the linker. */
1216     #define ODK_TAGS	6	/* reserve space for desktop tools to write. */
1217     #define ODK_HWAND	7	/* HW workarounds.  'AND' bits when merging. */
1218     #define ODK_HWOR	8	/* HW workarounds.  'OR' bits when merging.  */
1219     
1220     /* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries.  */
1221     
1222     #define OEX_FPU_MIN	0x1f	/* FPE's which MUST be enabled.  */
1223     #define OEX_FPU_MAX	0x1f00	/* FPE's which MAY be enabled.  */
1224     #define OEX_PAGE0	0x10000	/* page zero must be mapped.  */
1225     #define OEX_SMM		0x20000	/* Force sequential memory mode?  */
1226     #define OEX_FPDBUG	0x40000	/* Force floating point debug mode?  */
1227     #define OEX_PRECISEFP	OEX_FPDBUG
1228     #define OEX_DISMISS	0x80000	/* Dismiss invalid address faults?  */
1229     
1230     #define OEX_FPU_INVAL	0x10
1231     #define OEX_FPU_DIV0	0x08
1232     #define OEX_FPU_OFLO	0x04
1233     #define OEX_FPU_UFLO	0x02
1234     #define OEX_FPU_INEX	0x01
1235     
1236     /* Masks for `info' in Elf_Options for an ODK_HWPATCH entry.  */
1237     
1238     #define OHW_R4KEOP	0x1	/* R4000 end-of-page patch.  */
1239     #define OHW_R8KPFETCH	0x2	/* may need R8000 prefetch patch.  */
1240     #define OHW_R5KEOP	0x4	/* R5000 end-of-page patch.  */
1241     #define OHW_R5KCVTL	0x8	/* R5000 cvt.[ds].l bug.  clean=1.  */
1242     
1243     #define OPAD_PREFIX	0x1
1244     #define OPAD_POSTFIX	0x2
1245     #define OPAD_SYMBOL	0x4
1246     
1247     /* Entry found in `.options' section.  */
1248     
1249     typedef struct
1250     {
1251       Elf32_Word hwp_flags1;	/* Extra flags.  */
1252       Elf32_Word hwp_flags2;	/* Extra flags.  */
1253     } Elf_Options_Hw;
1254     
1255     /* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries.  */
1256     
1257     #define OHWA0_R4KEOP_CHECKED	0x00000001
1258     #define OHWA1_R4KEOP_CLEAN	0x00000002
1259     
1260     /* MIPS relocs.  */
1261     
1262     #define R_MIPS_NONE		0	/* No reloc */
1263     #define R_MIPS_16		1	/* Direct 16 bit */
1264     #define R_MIPS_32		2	/* Direct 32 bit */
1265     #define R_MIPS_REL32		3	/* PC relative 32 bit */
1266     #define R_MIPS_26		4	/* Direct 26 bit shifted */
1267     #define R_MIPS_HI16		5	/* High 16 bit */
1268     #define R_MIPS_LO16		6	/* Low 16 bit */
1269     #define R_MIPS_GPREL16		7	/* GP relative 16 bit */
1270     #define R_MIPS_LITERAL		8	/* 16 bit literal entry */
1271     #define R_MIPS_GOT16		9	/* 16 bit GOT entry */
1272     #define R_MIPS_PC16		10	/* PC relative 16 bit */
1273     #define R_MIPS_CALL16		11	/* 16 bit GOT entry for function */
1274     #define R_MIPS_GPREL32		12	/* GP relative 32 bit */
1275     
1276     #define R_MIPS_SHIFT5		16
1277     #define R_MIPS_SHIFT6		17
1278     #define R_MIPS_64		18
1279     #define R_MIPS_GOT_DISP		19
1280     #define R_MIPS_GOT_PAGE		20
1281     #define R_MIPS_GOT_OFST		21
1282     #define R_MIPS_GOT_HI16		22
1283     #define R_MIPS_GOT_LO16		23
1284     #define R_MIPS_SUB		24
1285     #define R_MIPS_INSERT_A		25
1286     #define R_MIPS_INSERT_B		26
1287     #define R_MIPS_DELETE		27
1288     #define R_MIPS_HIGHER		28
1289     #define R_MIPS_HIGHEST		29
1290     #define R_MIPS_CALL_HI16	30
1291     #define R_MIPS_CALL_LO16	31
1292     #define R_MIPS_SCN_DISP		32
1293     #define R_MIPS_REL16		33
1294     #define R_MIPS_ADD_IMMEDIATE	34
1295     #define R_MIPS_PJUMP		35
1296     #define R_MIPS_RELGOT		36
1297     #define R_MIPS_JALR		37
1298     /* Keep this the last entry.  */
1299     #define R_MIPS_NUM		38
1300     
1301     /* Legal values for p_type field of Elf32_Phdr.  */
1302     
1303     #define PT_MIPS_REGINFO	0x70000000	/* Register usage information */
1304     #define PT_MIPS_RTPROC  0x70000001	/* Runtime procedure table. */
1305     #define PT_MIPS_OPTIONS 0x70000002
1306     
1307     /* Special program header types.  */
1308     
1309     #define PF_MIPS_LOCAL	0x10000000
1310     
1311     /* Legal values for d_tag field of Elf32_Dyn.  */
1312     
1313     #define DT_MIPS_RLD_VERSION  0x70000001	/* Runtime linker interface version */
1314     #define DT_MIPS_TIME_STAMP   0x70000002	/* Timestamp */
1315     #define DT_MIPS_ICHECKSUM    0x70000003	/* Checksum */
1316     #define DT_MIPS_IVERSION     0x70000004	/* Version string (string tbl index) */
1317     #define DT_MIPS_FLAGS	     0x70000005	/* Flags */
1318     #define DT_MIPS_BASE_ADDRESS 0x70000006	/* Base address */
1319     #define DT_MIPS_MSYM	     0x70000007
1320     #define DT_MIPS_CONFLICT     0x70000008	/* Address of CONFLICT section */
1321     #define DT_MIPS_LIBLIST	     0x70000009	/* Address of LIBLIST section */
1322     #define DT_MIPS_LOCAL_GOTNO  0x7000000a	/* Number of local GOT entries */
1323     #define DT_MIPS_CONFLICTNO   0x7000000b	/* Number of CONFLICT entries */
1324     #define DT_MIPS_LIBLISTNO    0x70000010	/* Number of LIBLIST entries */
1325     #define DT_MIPS_SYMTABNO     0x70000011	/* Number of DYNSYM entries */
1326     #define DT_MIPS_UNREFEXTNO   0x70000012	/* First external DYNSYM */
1327     #define DT_MIPS_GOTSYM	     0x70000013	/* First GOT entry in DYNSYM */
1328     #define DT_MIPS_HIPAGENO     0x70000014	/* Number of GOT page table entries */
1329     #define DT_MIPS_RLD_MAP	     0x70000016	/* Address of run time loader map.  */
1330     #define DT_MIPS_DELTA_CLASS  0x70000017	/* Delta C++ class definition.  */
1331     #define DT_MIPS_DELTA_CLASS_NO    0x70000018 /* Number of entries in
1332     						DT_MIPS_DELTA_CLASS.  */
1333     #define DT_MIPS_DELTA_INSTANCE    0x70000019 /* Delta C++ class instances.  */
1334     #define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in
1335     						DT_MIPS_DELTA_INSTANCE.  */
1336     #define DT_MIPS_DELTA_RELOC  0x7000001b /* Delta relocations.  */
1337     #define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in
1338     					     DT_MIPS_DELTA_RELOC.  */
1339     #define DT_MIPS_DELTA_SYM    0x7000001d /* Delta symbols that Delta
1340     					   relocations refer to.  */
1341     #define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in
1342     					   DT_MIPS_DELTA_SYM.  */
1343     #define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the
1344     					     class declaration.  */
1345     #define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in
1346     						DT_MIPS_DELTA_CLASSSYM.  */
1347     #define DT_MIPS_CXX_FLAGS    0x70000022 /* Flags indicating for C++ flavor.  */
1348     #define DT_MIPS_PIXIE_INIT   0x70000023
1349     #define DT_MIPS_SYMBOL_LIB   0x70000024
1350     #define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
1351     #define DT_MIPS_LOCAL_GOTIDX 0x70000026
1352     #define DT_MIPS_HIDDEN_GOTIDX 0x70000027
1353     #define DT_MIPS_PROTECTED_GOTIDX 0x70000028
1354     #define DT_MIPS_OPTIONS	     0x70000029 /* Address of .options.  */
1355     #define DT_MIPS_INTERFACE    0x7000002a /* Address of .interface.  */
1356     #define DT_MIPS_DYNSTR_ALIGN 0x7000002b
1357     #define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */
1358     #define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve
1359     						    function stored in GOT.  */
1360     #define DT_MIPS_PERF_SUFFIX  0x7000002e /* Default suffix of dso to be added
1361     					   by rld on dlopen() calls.  */
1362     #define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */
1363     #define DT_MIPS_GP_VALUE     0x70000030 /* GP value for aux GOTs.  */
1364     #define DT_MIPS_AUX_DYNAMIC  0x70000031 /* Address of aux .dynamic.  */
1365     #define DT_MIPS_NUM	     0x32
1366     
1367     /* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry.  */
1368     
1369     #define RHF_NONE		   0		/* No flags */
1370     #define RHF_QUICKSTART		   (1 << 0)	/* Use quickstart */
1371     #define RHF_NOTPOT		   (1 << 1)	/* Hash size not power of 2 */
1372     #define RHF_NO_LIBRARY_REPLACEMENT (1 << 2)	/* Ignore LD_LIBRARY_PATH */
1373     #define RHF_NO_MOVE		   (1 << 3)
1374     #define RHF_SGI_ONLY		   (1 << 4)
1375     #define RHF_GUARANTEE_INIT	   (1 << 5)
1376     #define RHF_DELTA_C_PLUS_PLUS	   (1 << 6)
1377     #define RHF_GUARANTEE_START_INIT   (1 << 7)
1378     #define RHF_PIXIE		   (1 << 8)
1379     #define RHF_DEFAULT_DELAY_LOAD	   (1 << 9)
1380     #define RHF_REQUICKSTART	   (1 << 10)
1381     #define RHF_REQUICKSTARTED	   (1 << 11)
1382     #define RHF_CORD		   (1 << 12)
1383     #define RHF_NO_UNRES_UNDEF	   (1 << 13)
1384     #define RHF_RLD_ORDER_SAFE	   (1 << 14)
1385     
1386     /* Entries found in sections of type SHT_MIPS_LIBLIST.  */
1387     
1388     typedef struct
1389     {
1390       Elf32_Word l_name;		/* Name (string table index) */
1391       Elf32_Word l_time_stamp;	/* Timestamp */
1392       Elf32_Word l_checksum;	/* Checksum */
1393       Elf32_Word l_version;		/* Interface version */
1394       Elf32_Word l_flags;		/* Flags */
1395     } Elf32_Lib;
1396     
1397     typedef struct
1398     {
1399       Elf64_Word l_name;		/* Name (string table index) */
1400       Elf64_Word l_time_stamp;	/* Timestamp */
1401       Elf64_Word l_checksum;	/* Checksum */
1402       Elf64_Word l_version;		/* Interface version */
1403       Elf64_Word l_flags;		/* Flags */
1404     } Elf64_Lib;
1405     
1406     
1407     /* Legal values for l_flags.  */
1408     
1409     #define LL_NONE		  0
1410     #define LL_EXACT_MATCH	  (1 << 0)	/* Require exact match */
1411     #define LL_IGNORE_INT_VER (1 << 1)	/* Ignore interface version */
1412     #define LL_REQUIRE_MINOR  (1 << 2)
1413     #define LL_EXPORTS	  (1 << 3)
1414     #define LL_DELAY_LOAD	  (1 << 4)
1415     #define LL_DELTA	  (1 << 5)
1416     
1417     /* Entries found in sections of type SHT_MIPS_CONFLICT.  */
1418     
1419     typedef Elf32_Addr Elf32_Conflict;
1420     
1421     
1422     /* HPPA specific definitions.  */
1423     
1424     /* Legal values for e_flags field of Elf32_Ehdr.  */
1425     
1426     #define EF_PARISC_TRAPNL	1	/* Trap nil pointer dereference.  */
1427     #define EF_PARISC_EXT		2	/* Program uses arch. extensions.  */
1428     #define EF_PARISC_ARCH		0xffff0000 /* Architecture version.  */
1429     /* Defined values are:
1430     				0x020b	PA-RISC 1.0 big-endian
1431     				0x0210	PA-RISC 1.1 big-endian
1432     				0x028b	PA-RISC 1.0 little-endian
1433     				0x0290	PA-RISC 1.1 little-endian
1434     */
1435     
1436     /* Legal values for sh_type field of Elf32_Shdr.  */
1437     
1438     #define SHT_PARISC_GOT		0x70000000 /* GOT for external data.  */
1439     #define SHT_PARISC_ARCH		0x70000001 /* Architecture extensions.  */
1440     #define SHT_PARISC_GLOBAL	0x70000002 /* Definition of $global$.  */
1441     #define SHT_PARISC_MILLI	0x70000003 /* Millicode routines.  */
1442     #define SHT_PARISC_UNWIND	0x70000004 /* Unwind information.  */
1443     #define SHT_PARISC_PLT		0x70000005 /* Procedure linkage table.  */
1444     #define SHT_PARISC_SDATA	0x70000006 /* Short initialized data.  */
1445     #define SHT_PARISC_SBSS		0x70000007 /* Short uninitialized data.  */
1446     #define SHT_PARISC_SYMEXTN	0x70000008 /* Argument/relocation info.  */
1447     #define SHT_PARISC_STUBS	0x70000009 /* Linker stubs.  */
1448     
1449     /* Legal values for sh_flags field of Elf32_Shdr.  */
1450     
1451     #define SHF_PARISC_GLOBAL	0x10000000 /* Section defines dp.  */
1452     #define SHF_PARISC_SHORT	0x20000000 /* Section with short addressing. */
1453     
1454     /* Legal values for ST_TYPE subfield of st_info (symbol type).  */
1455     
1456     #define STT_PARISC_MILLICODE	13	/* Millicode function entry point.  */
1457     
1458     /* HPPA relocs.  */
1459     
1460     #define R_PARISC_NONE		0	/* No reloc.  */
1461     #define R_PARISC_DIR32		1	/* Direct 32-bit reference.  */
1462     #define R_PARISC_DIR21L		2	/* Left 21 bits of eff. address.  */
1463     #define R_PARISC_DIR17R		3	/* Right 17 bits of eff. address.  */
1464     #define R_PARISC_DIR14R		4	/* Right 14 bits of eff. address.  */
1465     #define R_PARISC_PCREL21L	5	/* PC-relative, left 21 bits.  */
1466     #define R_PARISC_PCREL14R	6	/* PC-relative, right 14 bits.  */
1467     #define R_PARISC_PCREL17C	7	/* Conditional PC-relative, ignore
1468     					   if displacement > 17bits.  */
1469     #define R_PARISC_PCREL17F	8	/* Conditional PC-relative, must
1470     					   fit in 17bits.  */
1471     #define R_PARISC_DPREL21L	9	/* DP-relative, left 21 bits.  */
1472     #define R_PARISC_DPREL14R	10	/* DP-relative, right 14 bits.  */
1473     #define R_PARISC_DPREL14F	11	/* DP-relative, must bit in 14 bits. */
1474     #define R_PARISC_DLTREL21L	12	/* DLT-relative, left 21 bits.  */
1475     #define R_PARISC_DLTREL14R	13	/* DLT-relative, right 14 bits.  */
1476     #define R_PARISC_DLTREL14F	14	/* DLT-relative, must fit in 14 bits.*/
1477     #define R_PARISC_DLTIND21L	15	/* DLT-relative indirect, left
1478     					   21 bits.  */
1479     #define R_PARISC_DLTIND14R	16	/* DLT-relative indirect, right
1480     					   14 bits.  */
1481     #define R_PARISC_DLTIND14F	17	/* DLT-relative indirect, must fit
1482     					   int 14 bits.  */
1483     #define R_PARISC_PLABEL32	18	/* Direct 32-bit reference to proc.  */
1484     
1485     /* Alpha specific definitions.  */
1486     
1487     /* Legal values for e_flags field of Elf64_Ehdr.  */
1488     
1489     #define EF_ALPHA_32BIT		1	/* All addresses must be < 2GB.  */
1490     #define EF_ALPHA_CANRELAX	2	/* Relocations for relaxing exist.  */
1491     
1492     /* Legal values for sh_type field of Elf64_Shdr.  */
1493     
1494     /* These two are primerily concerned with ECOFF debugging info.  */
1495     #define SHT_ALPHA_DEBUG		0x70000001
1496     #define SHT_ALPHA_REGINFO	0x70000002
1497     
1498     /* Legal values for sh_flags field of Elf64_Shdr.  */
1499     
1500     #define SHF_ALPHA_GPREL		0x10000000
1501     
1502     /* Legal values for st_other field of Elf64_Sym.  */
1503     #define STO_ALPHA_NOPV		0x80	/* No PV required.  */
1504     #define STO_ALPHA_STD_GPLOAD	0x88	/* PV only used for initial ldgp.  */
1505     
1506     /* Alpha relocs.  */
1507     
1508     #define R_ALPHA_NONE		0	/* No reloc */
1509     #define R_ALPHA_REFLONG		1	/* Direct 32 bit */
1510     #define R_ALPHA_REFQUAD		2	/* Direct 64 bit */
1511     #define R_ALPHA_GPREL32		3	/* GP relative 32 bit */
1512     #define R_ALPHA_LITERAL		4	/* GP relative 16 bit w/optimization */
1513     #define R_ALPHA_LITUSE		5	/* Optimization hint for LITERAL */
1514     #define R_ALPHA_GPDISP		6	/* Add displacement to GP */
1515     #define R_ALPHA_BRADDR		7	/* PC+4 relative 23 bit shifted */
1516     #define R_ALPHA_HINT		8	/* PC+4 relative 16 bit shifted */
1517     #define R_ALPHA_SREL16		9	/* PC relative 16 bit */
1518     #define R_ALPHA_SREL32		10	/* PC relative 32 bit */
1519     #define R_ALPHA_SREL64		11	/* PC relative 64 bit */
1520     #define R_ALPHA_OP_PUSH		12	/* OP stack push */
1521     #define R_ALPHA_OP_STORE	13	/* OP stack pop and store */
1522     #define R_ALPHA_OP_PSUB		14	/* OP stack subtract */
1523     #define R_ALPHA_OP_PRSHIFT	15	/* OP stack right shift */
1524     #define R_ALPHA_GPVALUE		16
1525     #define R_ALPHA_GPRELHIGH	17
1526     #define R_ALPHA_GPRELLOW	18
1527     #define R_ALPHA_IMMED_GP_16	19
1528     #define R_ALPHA_IMMED_GP_HI32	20
1529     #define R_ALPHA_IMMED_SCN_HI32	21
1530     #define R_ALPHA_IMMED_BR_HI32	22
1531     #define R_ALPHA_IMMED_LO32	23
1532     #define R_ALPHA_COPY		24	/* Copy symbol at runtime */
1533     #define R_ALPHA_GLOB_DAT	25	/* Create GOT entry */
1534     #define R_ALPHA_JMP_SLOT	26	/* Create PLT entry */
1535     #define R_ALPHA_RELATIVE	27	/* Adjust by program base */
1536     /* Keep this the last entry.  */
1537     #define R_ALPHA_NUM		28
1538     
1539     
1540     /* PowerPC specific declarations */
1541     
1542     /* PowerPC relocations defined by the ABIs */
1543     #define R_PPC_NONE		0
1544     #define R_PPC_ADDR32		1	/* 32bit absolute address */
1545     #define R_PPC_ADDR24		2	/* 26bit address, 2 bits ignored.  */
1546     #define R_PPC_ADDR16		3	/* 16bit absolute address */
1547     #define R_PPC_ADDR16_LO		4	/* lower 16bit of absolute address */
1548     #define R_PPC_ADDR16_HI		5	/* high 16bit of absolute address */
1549     #define R_PPC_ADDR16_HA		6	/* adjusted high 16bit */
1550     #define R_PPC_ADDR14		7	/* 16bit address, 2 bits ignored */
1551     #define R_PPC_ADDR14_BRTAKEN	8
1552     #define R_PPC_ADDR14_BRNTAKEN	9
1553     #define R_PPC_REL24		10	/* PC relative 26 bit */
1554     #define R_PPC_REL14		11	/* PC relative 16 bit */
1555     #define R_PPC_REL14_BRTAKEN	12
1556     #define R_PPC_REL14_BRNTAKEN	13
1557     #define R_PPC_GOT16		14
1558     #define R_PPC_GOT16_LO		15
1559     #define R_PPC_GOT16_HI		16
1560     #define R_PPC_GOT16_HA		17
1561     #define R_PPC_PLTREL24		18
1562     #define R_PPC_COPY		19
1563     #define R_PPC_GLOB_DAT		20
1564     #define R_PPC_JMP_SLOT		21
1565     #define R_PPC_RELATIVE		22
1566     #define R_PPC_LOCAL24PC		23
1567     #define R_PPC_UADDR32		24
1568     #define R_PPC_UADDR16		25
1569     #define R_PPC_REL32		26
1570     #define R_PPC_PLT32		27
1571     #define R_PPC_PLTREL32		28
1572     #define R_PPC_PLT16_LO		29
1573     #define R_PPC_PLT16_HI		30
1574     #define R_PPC_PLT16_HA		31
1575     #define R_PPC_SDAREL16		32
1576     #define R_PPC_SECTOFF		33
1577     #define R_PPC_SECTOFF_LO	34
1578     #define R_PPC_SECTOFF_HI	35
1579     #define R_PPC_SECTOFF_HA	36
1580     /* Keep this the last entry.  */
1581     #define R_PPC_NUMm		37
1582     
1583     /* The remaining relocs are from the Embedded ELF ABI, and are not
1584        in the SVR4 ELF ABI.  */
1585     #define R_PPC_EMB_NADDR32	101
1586     #define R_PPC_EMB_NADDR16	102
1587     #define R_PPC_EMB_NADDR16_LO	103
1588     #define R_PPC_EMB_NADDR16_HI	104
1589     #define R_PPC_EMB_NADDR16_HA	105
1590     #define R_PPC_EMB_SDAI16	106
1591     #define R_PPC_EMB_SDA2I16	107
1592     #define R_PPC_EMB_SDA2REL	108
1593     #define R_PPC_EMB_SDA21		109	/* 16 bit offset in SDA */
1594     #define R_PPC_EMB_MRKREF	110
1595     #define R_PPC_EMB_RELSEC16	111
1596     #define R_PPC_EMB_RELST_LO	112
1597     #define R_PPC_EMB_RELST_HI	113
1598     #define R_PPC_EMB_RELST_HA	114
1599     #define R_PPC_EMB_BIT_FLD	115
1600     #define R_PPC_EMB_RELSDA	116	/* 16 bit relative offset in SDA */
1601     
1602     /* Diab tool relocations.  */
1603     #define R_PPC_DIAB_SDA21_LO	180	/* like EMB_SDA21, but lower 16 bit */
1604     #define R_PPC_DIAB_SDA21_HI	181	/* like EMB_SDA21, but high 16 bit */
1605     #define R_PPC_DIAB_SDA21_HA	182	/* like EMB_SDA21, adjusted high 16 */
1606     #define R_PPC_DIAB_RELSDA_LO	183	/* like EMB_RELSDA, but lower 16 bit */
1607     #define R_PPC_DIAB_RELSDA_HI	184	/* like EMB_RELSDA, but high 16 bit */
1608     #define R_PPC_DIAB_RELSDA_HA	185	/* like EMB_RELSDA, adjusted high 16 */
1609     
1610     /* This is a phony reloc to handle any old fashioned TOC16 references
1611        that may still be in object files.  */
1612     #define R_PPC_TOC16		255
1613     
1614     
1615     /* ARM specific declarations */
1616     
1617     /* Processor specific flags for the ELF header e_flags field.  */
1618     #define EF_ARM_RELEXEC     0x01
1619     #define EF_ARM_HASENTRY    0x02
1620     #define EF_ARM_INTERWORK   0x04
1621     #define EF_ARM_APCS_26     0x08
1622     #define EF_ARM_APCS_FLOAT  0x10
1623     #define EF_ARM_PIC         0x20
1624     #define EF_ALIGN8          0x40		/* 8-bit structure alignment is in use */
1625     #define EF_NEW_ABI         0x80
1626     #define EF_OLD_ABI         0x100
1627     
1628     /* Additional symbol types for Thumb */
1629     #define STT_ARM_TFUNC      0xd
1630     
1631     /* ARM-specific values for sh_flags */
1632     #define SHF_ARM_ENTRYSECT  0x10000000   /* Section contains an entry point */
1633     #define SHF_ARM_COMDEF     0x80000000   /* Section may be multiply defined
1634     					   in the input to a link step */
1635     
1636     /* ARM-specific program header flags */
1637     #define PF_ARM_SB          0x10000000   /* Segment contains the location
1638     					   addressed by the static base */
1639     
1640     /* ARM relocs.  */
1641     #define R_ARM_NONE		0	/* No reloc */
1642     #define R_ARM_PC24		1	/* PC relative 26 bit branch */
1643     #define R_ARM_ABS32		2	/* Direct 32 bit  */
1644     #define R_ARM_REL32		3	/* PC relative 32 bit */
1645     #define R_ARM_PC13		4
1646     #define R_ARM_ABS16		5	/* Direct 16 bit */
1647     #define R_ARM_ABS12		6	/* Direct 12 bit */
1648     #define R_ARM_THM_ABS5		7
1649     #define R_ARM_ABS8		8	/* Direct 8 bit */
1650     #define R_ARM_SBREL32		9
1651     #define R_ARM_THM_PC22		10
1652     #define R_ARM_THM_PC8		11
1653     #define R_ARM_AMP_VCALL9	12
1654     #define R_ARM_SWI24		13
1655     #define R_ARM_THM_SWI8		14
1656     #define R_ARM_XPC25		15
1657     #define R_ARM_THM_XPC22		16
1658     #define R_ARM_COPY		20	/* Copy symbol at runtime */
1659     #define R_ARM_GLOB_DAT		21	/* Create GOT entry */
1660     #define R_ARM_JUMP_SLOT		22	/* Create PLT entry */
1661     #define R_ARM_RELATIVE		23	/* Adjust by program base */
1662     #define R_ARM_GOTOFF		24	/* 32 bit offset to GOT */
1663     #define R_ARM_GOTPC		25	/* 32 bit PC relative offset to GOT */
1664     #define R_ARM_GOT32		26	/* 32 bit GOT entry */
1665     #define R_ARM_PLT32		27	/* 32 bit PLT address */
1666     #define R_ARM_GNU_VTENTRY	100
1667     #define R_ARM_GNU_VTINHERIT	101
1668     #define R_ARM_THM_PC11		102	/* thumb unconditional branch */
1669     #define R_ARM_THM_PC9		103	/* thumb conditional branch */
1670     #define R_ARM_RXPC25		249
1671     #define R_ARM_RSBREL32		250
1672     #define R_ARM_THM_RPC22		251
1673     #define R_ARM_RREL32		252
1674     #define R_ARM_RABS22		253
1675     #define R_ARM_RPC24		254
1676     #define R_ARM_RBASE		255
1677     /* Keep this the last entry.  */
1678     #define R_ARM_NUM		256
1679     
1680     /* TMS320C67xx specific declarations */
1681     /* XXX: no ELF standard yet */
1682     
1683     /* TMS320C67xx relocs. */
1684     #define R_C60_32       1
1685     #define R_C60_GOT32	3		/* 32 bit GOT entry */
1686     #define R_C60_PLT32	4		/* 32 bit PLT address */
1687     #define R_C60_COPY	5		/* Copy symbol at runtime */
1688     #define R_C60_GLOB_DAT	6		/* Create GOT entry */
1689     #define R_C60_JMP_SLOT	7		/* Create PLT entry */
1690     #define R_C60_RELATIVE	8		/* Adjust by program base */
1691     #define R_C60_GOTOFF	9		/* 32 bit offset to GOT */
1692     #define R_C60_GOTPC	10		/* 32 bit PC relative offset to GOT */
1693     
1694     #define R_C60HI16      0x55       // high 16 bit MVKH embedded
1695     #define R_C60LO16      0x54       // low 16 bit MVKL embedded
1696     
1697     #endif	/* elf.h */
1698     //---------------------------------------------------------------------------
1699     
1700     
1701     // njn: inlined stab.h
1702     //#include "stab.h"
1703     //---------------------------------------------------------------------------
1704     #ifndef __GNU_STAB__
1705     
1706     /* Indicate the GNU stab.h is in use.  */
1707     
1708     #define __GNU_STAB__
1709     
1710     #define __define_stab(NAME, CODE, STRING) NAME=CODE,
1711     
1712     enum __stab_debug_code
1713     {
1714     // njn: inlined stab.def
1715     //#include "stab.def"
1716     //---------------------------------------------------------------------------
1717     /* Table of DBX symbol codes for the GNU system.
1718        Copyright (C) 1988, 1997 Free Software Foundation, Inc.
1719        This file is part of the GNU C Library.
1720     
1721        The GNU C Library is free software; you can redistribute it and/or
1722        modify it under the terms of the GNU Library General Public License as
1723        published by the Free Software Foundation; either version 2 of the
1724        License, or (at your option) any later version.
1725     
1726        The GNU C Library is distributed in the hope that it will be useful,
1727        but WITHOUT ANY WARRANTY; without even the implied warranty of
1728        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1729        Library General Public License for more details.
1730     
1731        You should have received a copy of the GNU Library General Public
1732        License along with the GNU C Library; see the file COPYING.LIB.  If not,
1733        write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
1734        Boston, MA 02111-1307, USA.  */
1735     
1736     /* This contains contribution from Cygnus Support.  */
1737     
1738     /* Global variable.  Only the name is significant.
1739        To find the address, look in the corresponding external symbol.  */
1740     __define_stab (N_GSYM, 0x20, "GSYM")
1741     
1742     /* Function name for BSD Fortran.  Only the name is significant.
1743        To find the address, look in the corresponding external symbol.  */
1744     __define_stab (N_FNAME, 0x22, "FNAME")
1745     
1746     /* Function name or text-segment variable for C.  Value is its address.
1747        Desc is supposedly starting line number, but GCC doesn't set it
1748        and DBX seems not to miss it.  */
1749     __define_stab (N_FUN, 0x24, "FUN")
1750     
1751     /* Data-segment variable with internal linkage.  Value is its address.
1752        "Static Sym".  */
1753     __define_stab (N_STSYM, 0x26, "STSYM")
1754     
1755     /* BSS-segment variable with internal linkage.  Value is its address.  */
1756     __define_stab (N_LCSYM, 0x28, "LCSYM")
1757     
1758     /* Name of main routine.  Only the name is significant.
1759        This is not used in C.  */
1760     __define_stab (N_MAIN, 0x2a, "MAIN")
1761     
1762     /* Global symbol in Pascal.
1763        Supposedly the value is its line number; I'm skeptical.  */
1764     __define_stab (N_PC, 0x30, "PC")
1765     
1766     /* Number of symbols:  0, files,,funcs,lines according to Ultrix V4.0. */
1767     __define_stab (N_NSYMS, 0x32, "NSYMS")
1768     
1769     /* "No DST map for sym: name, ,0,type,ignored"  according to Ultrix V4.0. */
1770     __define_stab (N_NOMAP, 0x34, "NOMAP")
1771     
1772     /* New stab from Solaris.  I don't know what it means, but it
1773        don't seem to contain useful information.  */
1774     __define_stab (N_OBJ, 0x38, "OBJ")
1775     
1776     /* New stab from Solaris.  I don't know what it means, but it
1777        don't seem to contain useful information.  Possibly related to the
1778        optimization flags used in this module.  */
1779     __define_stab (N_OPT, 0x3c, "OPT")
1780     
1781     /* Register variable.  Value is number of register.  */
1782     __define_stab (N_RSYM, 0x40, "RSYM")
1783     
1784     /* Modula-2 compilation unit.  Can someone say what info it contains?  */
1785     __define_stab (N_M2C, 0x42, "M2C")
1786     
1787     /* Line number in text segment.  Desc is the line number;
1788        value is corresponding address.  */
1789     __define_stab (N_SLINE, 0x44, "SLINE")
1790     
1791     /* Similar, for data segment.  */
1792     __define_stab (N_DSLINE, 0x46, "DSLINE")
1793     
1794     /* Similar, for bss segment.  */
1795     __define_stab (N_BSLINE, 0x48, "BSLINE")
1796     
1797     /* Sun's source-code browser stabs.  ?? Don't know what the fields are.
1798        Supposedly the field is "path to associated .cb file".  THIS VALUE
1799        OVERLAPS WITH N_BSLINE!  */
1800     __define_stab (N_BROWS, 0x48, "BROWS")
1801     
1802     /* GNU Modula-2 definition module dependency.  Value is the modification time
1803        of the definition file.  Other is non-zero if it is imported with the
1804        GNU M2 keyword %INITIALIZE.  Perhaps N_M2C can be used if there
1805        are enough empty fields? */
1806     __define_stab(N_DEFD, 0x4a, "DEFD")
1807     
1808     /* THE FOLLOWING TWO STAB VALUES CONFLICT.  Happily, one is for Modula-2
1809        and one is for C++.   Still,... */
1810     /* GNU C++ exception variable.  Name is variable name.  */
1811     __define_stab (N_EHDECL, 0x50, "EHDECL")
1812     /* Modula2 info "for imc":  name,,0,0,0  according to Ultrix V4.0.  */
1813     __define_stab (N_MOD2, 0x50, "MOD2")
1814     
1815     /* GNU C++ `catch' clause.  Value is its address.  Desc is nonzero if
1816        this entry is immediately followed by a CAUGHT stab saying what exception
1817        was caught.  Multiple CAUGHT stabs means that multiple exceptions
1818        can be caught here.  If Desc is 0, it means all exceptions are caught
1819        here.  */
1820     __define_stab (N_CATCH, 0x54, "CATCH")
1821     
1822     /* Structure or union element.  Value is offset in the structure.  */
1823     __define_stab (N_SSYM, 0x60, "SSYM")
1824     
1825     /* Name of main source file.
1826        Value is starting text address of the compilation.  */
1827     __define_stab (N_SO, 0x64, "SO")
1828     
1829     /* Automatic variable in the stack.  Value is offset from frame pointer.
1830        Also used for type descriptions.  */
1831     __define_stab (N_LSYM, 0x80, "LSYM")
1832     
1833     /* Beginning of an include file.  Only Sun uses this.
1834        In an object file, only the name is significant.
1835        The Sun linker puts data into some of the other fields.  */
1836     __define_stab (N_BINCL, 0x82, "BINCL")
1837     
1838     /* Name of sub-source file (#include file).
1839        Value is starting text address of the compilation.  */
1840     __define_stab (N_SOL, 0x84, "SOL")
1841     
1842     /* Parameter variable.  Value is offset from argument pointer.
1843        (On most machines the argument pointer is the same as the frame pointer.  */
1844     __define_stab (N_PSYM, 0xa0, "PSYM")
1845     
1846     /* End of an include file.  No name.
1847        This and N_BINCL act as brackets around the file's output.
1848        In an object file, there is no significant data in this entry.
1849        The Sun linker puts data into some of the fields.  */
1850     __define_stab (N_EINCL, 0xa2, "EINCL")
1851     
1852     /* Alternate entry point.  Value is its address.  */
1853     __define_stab (N_ENTRY, 0xa4, "ENTRY")
1854     
1855     /* Beginning of lexical block.
1856        The desc is the nesting level in lexical blocks.
1857        The value is the address of the start of the text for the block.
1858        The variables declared inside the block *precede* the N_LBRAC symbol.  */
1859     __define_stab (N_LBRAC, 0xc0, "LBRAC")
1860     
1861     /* Place holder for deleted include file.  Replaces a N_BINCL and everything
1862        up to the corresponding N_EINCL.  The Sun linker generates these when
1863        it finds multiple identical copies of the symbols from an include file.
1864        This appears only in output from the Sun linker.  */
1865     __define_stab (N_EXCL, 0xc2, "EXCL")
1866     
1867     /* Modula-2 scope information.  Can someone say what info it contains?  */
1868     __define_stab (N_SCOPE, 0xc4, "SCOPE")
1869     
1870     /* End of a lexical block.  Desc matches the N_LBRAC's desc.
1871        The value is the address of the end of the text for the block.  */
1872     __define_stab (N_RBRAC, 0xe0, "RBRAC")
1873     
1874     /* Begin named common block.  Only the name is significant.  */
1875     __define_stab (N_BCOMM, 0xe2, "BCOMM")
1876     
1877     /* End named common block.  Only the name is significant
1878        (and it should match the N_BCOMM).  */
1879     __define_stab (N_ECOMM, 0xe4, "ECOMM")
1880     
1881     /* End common (local name): value is address.
1882        I'm not sure how this is used.  */
1883     __define_stab (N_ECOML, 0xe8, "ECOML")
1884     
1885     /* These STAB's are used on Gould systems for Non-Base register symbols
1886        or something like that.  FIXME.  I have assigned the values at random
1887        since I don't have a Gould here.  Fixups from Gould folk welcome... */
1888     __define_stab (N_NBTEXT, 0xF0, "NBTEXT")
1889     __define_stab (N_NBDATA, 0xF2, "NBDATA")
1890     __define_stab (N_NBBSS,  0xF4, "NBBSS")
1891     __define_stab (N_NBSTS,  0xF6, "NBSTS")
1892     __define_stab (N_NBLCS,  0xF8, "NBLCS")
1893     
1894     /* Second symbol entry containing a length-value for the preceding entry.
1895        The value is the length.  */
1896     __define_stab (N_LENG, 0xfe, "LENG")
1897     
1898     /* The above information, in matrix format.
1899     
1900     			STAB MATRIX
1901     	_________________________________________________
1902     	| 00 - 1F are not dbx stab symbols		|
1903     	| In most cases, the low bit is the EXTernal bit|
1904     
1905     	| 00 UNDEF  | 02 ABS	| 04 TEXT   | 06 DATA	|
1906     	| 01  |EXT  | 03  |EXT	| 05  |EXT  | 07  |EXT	|
1907     
1908     	| 08 BSS    | 0A INDR	| 0C FN_SEQ | 0E   	|
1909     	| 09  |EXT  | 0B 	| 0D	    | 0F	|
1910     
1911     	| 10 	    | 12 COMM	| 14 SETA   | 16 SETT	|
1912     	| 11	    | 13	| 15 	    | 17	|
1913     
1914     	| 18 SETD   | 1A SETB	| 1C SETV   | 1E WARNING|
1915     	| 19	    | 1B	| 1D 	    | 1F FN	|
1916     
1917     	|_______________________________________________|
1918     	| Debug entries with bit 01 set are unused.	|
1919     	| 20 GSYM   | 22 FNAME	| 24 FUN    | 26 STSYM	|
1920     	| 28 LCSYM  | 2A MAIN	| 2C	    | 2E	|
1921     	| 30 PC	    | 32 NSYMS	| 34 NOMAP  | 36	|
1922     	| 38 OBJ    | 3A	| 3C OPT    | 3E	|
1923     	| 40 RSYM   | 42 M2C	| 44 SLINE  | 46 DSLINE |
1924     	| 48 BSLINE*| 4A DEFD	| 4C        | 4E	|
1925     	| 50 EHDECL*| 52	| 54 CATCH  | 56        |
1926     	| 58        | 5A        | 5C        | 5E	|
1927     	| 60 SSYM   | 62	| 64 SO	    | 66 	|
1928     	| 68 	    | 6A	| 6C	    | 6E	|
1929     	| 70	    | 72	| 74	    | 76	|
1930     	| 78	    | 7A	| 7C	    | 7E	|
1931     	| 80 LSYM   | 82 BINCL	| 84 SOL    | 86	|
1932     	| 88	    | 8A	| 8C	    | 8E	|
1933     	| 90	    | 92	| 94	    | 96	|
1934     	| 98	    | 9A	| 9C	    | 9E	|
1935     	| A0 PSYM   | A2 EINCL	| A4 ENTRY  | A6	|
1936     	| A8	    | AA	| AC	    | AE	|
1937     	| B0	    | B2	| B4	    | B6	|
1938     	| B8	    | BA	| BC	    | BE	|
1939     	| C0 LBRAC  | C2 EXCL	| C4 SCOPE  | C6	|
1940     	| C8	    | CA	| CC	    | CE	|
1941     	| D0	    | D2	| D4	    | D6	|
1942     	| D8	    | DA	| DC	    | DE	|
1943     	| E0 RBRAC  | E2 BCOMM	| E4 ECOMM  | E6	|
1944     	| E8 ECOML  | EA	| EC	    | EE	|
1945     	| F0	    | F2	| F4	    | F6	|
1946     	| F8	    | FA	| FC	    | FE LENG	|
1947     	+-----------------------------------------------+
1948      * 50 EHDECL is also MOD2.
1949      * 48 BSLINE is also BROWS.
1950      */
1951     //---------------------------------------------------------------------------
1952     LAST_UNUSED_STAB_CODE
1953     };
1954     
1955     #undef __define_stab
1956     
1957     #endif /* __GNU_STAB_ */
1958     //---------------------------------------------------------------------------
1959     
1960     #ifndef O_BINARY
1961     #define O_BINARY 0
1962     #endif
1963     
1964     // njn: inlined libtcc.h
1965     //#include "libtcc.h"
1966     //---------------------------------------------------------------------------
1967     #ifndef LIBTCC_H
1968     #define LIBTCC_H
1969     
1970     #ifdef __cplusplus
1971     extern "C" {
1972     #endif
1973     
1974     struct TCCState;
1975     
1976     typedef struct TCCState TCCState;
1977     
1978     /* create a new TCC compilation context */
1979     TCCState *tcc_new(void);
1980     
1981     /* free a TCC compilation context */
1982     void tcc_delete(TCCState *s);
1983     
1984     /* add debug information in the generated code */
1985     void tcc_enable_debug(TCCState *s);
1986     
1987     /* set error/warning display callback */
1988     void tcc_set_error_func(TCCState *s, void *error_opaque,
1989                             void (*error_func)(void *opaque, const char *msg));
1990     
1991     /* set/reset a warning */
1992     int tcc_set_warning(TCCState *s, const char *warning_name, int value);
1993     
1994     /*****************************/
1995     /* preprocessor */
1996     
1997     /* add include path */
1998     int tcc_add_include_path(TCCState *s, const char *pathname);
1999     
2000     /* add in system include path */
2001     int tcc_add_sysinclude_path(TCCState *s, const char *pathname);
2002     
2003     /* define preprocessor symbol 'sym'. Can put optional value */
2004     void tcc_define_symbol(TCCState *s, const char *sym, const char *value);
2005     
2006     /* undefine preprocess symbol 'sym' */
2007     void tcc_undefine_symbol(TCCState *s, const char *sym);
2008     
2009     /*****************************/
2010     /* compiling */
2011     
2012     /* add a file (either a C file, dll, an object, a library or an ld
2013        script). Return -1 if error. */
2014     int tcc_add_file(TCCState *s, const char *filename);
2015     
2016     /* compile a string containing a C source. Return non zero if
2017        error. */
2018     int tcc_compile_string(TCCState *s, const char *buf);
2019     
2020     /*****************************/
2021     /* linking commands */
2022     
2023     /* set output type. MUST BE CALLED before any compilation */
2024     #define TCC_OUTPUT_MEMORY   0 /* output will be ran in memory (no
2025                                      output file) (default) */
2026     #define TCC_OUTPUT_EXE      1 /* executable file */
2027     #define TCC_OUTPUT_DLL      2 /* dynamic library */
2028     #define TCC_OUTPUT_OBJ      3 /* object file */
2029     int tcc_set_output_type(TCCState *s, int output_type);
2030     
2031     #define TCC_OUTPUT_FORMAT_ELF    0 /* default output format: ELF */
2032     #define TCC_OUTPUT_FORMAT_BINARY 1 /* binary image output */
2033     #define TCC_OUTPUT_FORMAT_COFF   2 /* COFF */
2034     
2035     /* equivalent to -Lpath option */
2036     int tcc_add_library_path(TCCState *s, const char *pathname);
2037     
2038     /* the library name is the same as the argument of the '-l' option */
2039     int tcc_add_library(TCCState *s, const char *libraryname);
2040     
2041     /* add a symbol to the compiled program */
2042     int tcc_add_symbol(TCCState *s, const char *name, unsigned long val);
2043     
2044     /* output an executable, library or object file. DO NOT call
2045        tcc_relocate() before. */
2046     int tcc_output_file(TCCState *s, const char *filename);
2047     
2048     /* link and run main() function and return its value. DO NOT call
2049        tcc_relocate() before. */
2050     int tcc_run(TCCState *s, int argc, char **argv);
2051     
2052     /* do all relocations (needed before using tcc_get_symbol()). Return
2053        non zero if link error. */
2054     int tcc_relocate(TCCState *s);
2055     
2056     /* return symbol value. return 0 if OK, -1 if symbol not found */
2057     int tcc_get_symbol(TCCState *s, unsigned long *pval, const char *name);
2058     
2059     #ifdef __cplusplus
2060     }
2061     #endif
2062     
2063     #endif
2064     //---------------------------------------------------------------------------
2065     
2066     /* parser debug */
2067     //#define PARSE_DEBUG
2068     /* preprocessor debug */
2069     //#define PP_DEBUG
2070     /* include file debug */
2071     //#define INC_DEBUG
2072     
2073     //#define MEM_DEBUG
2074     
2075     /* assembler debug */
2076     //#define ASM_DEBUG
2077     
2078     /* target selection */
2079     //#define TCC_TARGET_I386   /* i386 code generator */
2080     //#define TCC_TARGET_ARM    /* ARMv4 code generator */
2081     //#define TCC_TARGET_C67    /* TMS320C67xx code generator */
2082     
2083     /* default target is I386 */
2084     #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \
2085         !defined(TCC_TARGET_C67)
2086     #define TCC_TARGET_I386
2087     #endif
2088     
2089     #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \
2090         !defined(TCC_TARGET_C67)
2091     #define CONFIG_TCC_BCHECK /* enable bound checking code */
2092     #endif
2093     
2094     #if defined(WIN32) && !defined(TCC_TARGET_PE)
2095     #define CONFIG_TCC_STATIC
2096     #endif
2097     
2098     /* define it to include assembler support */
2099     #if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_C67)
2100     #define CONFIG_TCC_ASM
2101     #endif
2102     
2103     /* object format selection */
2104     #if defined(TCC_TARGET_C67)
2105     #define TCC_TARGET_COFF
2106     #endif
2107     
2108     #define FALSE 0
2109     #define false 0
2110     #define TRUE 1
2111     #define true 1
2112     typedef int BOOL;
2113     
2114     /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
2115        executables or dlls */
2116     #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
2117     
2118     #define INCLUDE_STACK_SIZE  32
2119     #define IFDEF_STACK_SIZE    64
2120     #define VSTACK_SIZE         256
2121     #define STRING_MAX_SIZE     1024
2122     #define PACK_STACK_SIZE     8
2123     
2124     #define TOK_HASH_SIZE       8192 /* must be a power of two */
2125     #define TOK_ALLOC_INCR      512  /* must be a power of two */
2126     #define TOK_MAX_SIZE        4 /* token max size in int unit when stored in string */
2127     
2128     /* token symbol management */
2129     typedef struct TokenSym {
2130         struct TokenSym *hash_next;
2131         struct Sym *sym_define; /* direct pointer to define */
2132         struct Sym *sym_label; /* direct pointer to label */
2133         struct Sym *sym_struct; /* direct pointer to structure */
2134         struct Sym *sym_identifier; /* direct pointer to identifier */
2135         int tok; /* token number */
2136         int len;
2137         char str[1];
2138     } TokenSym;
2139     
2140     typedef struct CString {
2141         int size; /* size in bytes */
2142         void *data; /* either 'char *' or 'int *' */
2143         int size_allocated;
2144         void *data_allocated; /* if non NULL, data has been malloced */
2145     } CString;
2146     
2147     /* type definition */
2148     typedef struct CType {
2149         int t;
2150         struct Sym *ref;
2151     } CType;
2152     
2153     /* constant value */
2154     typedef union CValue {
2155         long double ld;
2156         double d;
2157         float f;
2158         int i;
2159         unsigned int ui;
2160         unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
2161         long long ll;
2162         unsigned long long ull;
2163         struct CString *cstr;
2164         void *ptr;
2165         int tab[1];
2166     } CValue;
2167     
2168     /* value on stack */
2169     typedef struct SValue {
2170         CType type;      /* type */
2171         unsigned short r;      /* register + flags */
2172         unsigned short r2;     /* second register, used for 'long long'
2173                                   type. If not used, set to VT_CONST */
2174         CValue c;              /* constant, if VT_CONST */
2175         struct Sym *sym;       /* symbol, if (VT_SYM | VT_CONST) */
2176     } SValue;
2177     
2178     /* symbol management */
2179     typedef struct Sym {
2180         long v;    /* symbol token */
2181         long r;    /* associated register */
2182         long c;    /* associated number */
2183         CType type;    /* associated type */
2184         struct Sym *next; /* next related symbol */
2185         struct Sym *prev; /* prev symbol in stack */
2186         struct Sym *prev_tok; /* previous symbol for this token */
2187     } Sym;
2188     
2189     /* section definition */
2190     /* XXX: use directly ELF structure for parameters ? */
2191     /* special flag to indicate that the section should not be linked to
2192        the other ones */
2193     #define SHF_PRIVATE 0x80000000
2194     
2195     typedef struct Section {
2196         unsigned long data_offset; /* current data offset */
2197         unsigned char *data;       /* section data */
2198         unsigned long data_allocated; /* used for realloc() handling */
2199         int sh_name;             /* elf section name (only used during output) */
2200         int sh_num;              /* elf section number */
2201         int sh_type;             /* elf section type */
2202         int sh_flags;            /* elf section flags */
2203         int sh_info;             /* elf section info */
2204         int sh_addralign;        /* elf section alignment */
2205         int sh_entsize;          /* elf entry size */
2206         unsigned long sh_size;   /* section size (only used during output) */
2207         unsigned long sh_addr;      /* address at which the section is relocated */
2208         unsigned long sh_offset;      /* address at which the section is relocated */
2209         int nb_hashed_syms;      /* used to resize the hash table */
2210         struct Section *link;    /* link to another section */
2211         struct Section *reloc;   /* corresponding section for relocation, if any */
2212         struct Section *hash;     /* hash table for symbols */
2213         struct Section *next;
2214         char name[1];           /* section name */
2215     } Section;
2216     
2217     typedef struct DLLReference {
2218         int level;
2219         char name[1];
2220     } DLLReference;
2221     
2222     /* GNUC attribute definition */
2223     typedef struct AttributeDef {
2224         int aligned;
2225         int packed; 
2226         Section *section;
2227         unsigned char func_call; /* FUNC_CDECL, FUNC_STDCALL, FUNC_FASTCALLx */
2228         unsigned char dllexport; 
2229     } AttributeDef;
2230     
2231     #define SYM_STRUCT     0x40000000 /* struct/union/enum symbol space */
2232     #define SYM_FIELD      0x20000000 /* struct/union field symbol space */
2233     #define SYM_FIRST_ANOM 0x10000000 /* first anonymous sym */
2234     
2235     /* stored in 'Sym.c' field */
2236     #define FUNC_NEW       1 /* ansi function prototype */
2237     #define FUNC_OLD       2 /* old function prototype */
2238     #define FUNC_ELLIPSIS  3 /* ansi function prototype with ... */
2239     
2240     /* stored in 'Sym.r' field */
2241     #define FUNC_CDECL     0 /* standard c call */
2242     #define FUNC_STDCALL   1 /* pascal c call */
2243     #define FUNC_FASTCALL1 2 /* first param in %eax */
2244     #define FUNC_FASTCALL2 3 /* first parameters in %eax, %edx */
2245     #define FUNC_FASTCALL3 4 /* first parameter in %eax, %edx, %ecx */
2246     
2247     /* field 'Sym.t' for macros */
2248     #define MACRO_OBJ      0 /* object like macro */
2249     #define MACRO_FUNC     1 /* function like macro */
2250     
2251     /* field 'Sym.r' for C labels */
2252     #define LABEL_DEFINED  0 /* label is defined */
2253     #define LABEL_FORWARD  1 /* label is forward defined */
2254     #define LABEL_DECLARED 2 /* label is declared but never used */
2255     
2256     /* type_decl() types */
2257     #define TYPE_ABSTRACT  1 /* type without variable */
2258     #define TYPE_DIRECT    2 /* type with variable */
2259     
2260     #define IO_BUF_SIZE 8192
2261     
2262     typedef struct BufferedFile {
2263         uint8_t *buf_ptr;
2264         uint8_t *buf_end;
2265         int fd;
2266         int line_num;    /* current line number - here to simplify code */
2267         int ifndef_macro;  /* #ifndef macro / #endif search */
2268         int ifndef_macro_saved; /* saved ifndef_macro */
2269         int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
2270         char inc_type;          /* type of include */
2271         char inc_filename[512]; /* filename specified by the user */
2272         char filename[1024];    /* current filename - here to simplify code */
2273         unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
2274     } BufferedFile;
2275     
2276     #define CH_EOB   '\\'       /* end of buffer or '\0' char in file */
2277     #define CH_EOF   (-1)   /* end of file */
2278     
2279     /* parsing state (used to save parser state to reparse part of the
2280        source several times) */
2281     typedef struct ParseState {
2282         int *macro_ptr;
2283         int line_num;
2284         int tok;
2285         CValue tokc;
2286     } ParseState;
2287     
2288     /* used to record tokens */
2289     typedef struct TokenString {
2290         int *str;
2291         int len;
2292         int allocated_len;
2293         int last_line_num;
2294     } TokenString;
2295     
2296     /* include file cache, used to find files faster and also to eliminate
2297        inclusion if the include file is protected by #ifndef ... #endif */
2298     typedef struct CachedInclude {
2299         int ifndef_macro;
2300         int hash_next; /* -1 if none */
2301         char type; /* '"' or '>' to give include type */
2302         char filename[1]; /* path specified in #include */
2303     } CachedInclude;
2304     
2305     #define CACHED_INCLUDES_HASH_SIZE 512
2306     
2307     /* parser */
2308     static struct BufferedFile *file;
2309     static int ch, tok;
2310     static CValue tokc;
2311     static CString tokcstr; /* current parsed string, if any */
2312     /* additional informations about token */
2313     static int tok_flags;
2314     #define TOK_FLAG_BOL   0x0001 /* beginning of line before */
2315     #define TOK_FLAG_BOF   0x0002 /* beginning of file before */
2316     #define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
2317     
2318     static int *macro_ptr, *macro_ptr_allocated;
2319     static int *unget_saved_macro_ptr;
2320     static int unget_saved_buffer[TOK_MAX_SIZE + 1];
2321     static int unget_buffer_enabled;
2322     static int parse_flags;
2323     #define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */
2324     #define PARSE_FLAG_TOK_NUM    0x0002 /* return numbers instead of TOK_PPNUM */
2325     #define PARSE_FLAG_LINEFEED   0x0004 /* line feed is returned as a
2326                                             token. line feed is also
2327                                             returned at eof */
2328     #define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */
2329      
2330     static Section *text_section, *data_section, *bss_section; /* predefined sections */
2331     static Section *cur_text_section; /* current section where function code is
2332                                   generated */
2333     #ifdef CONFIG_TCC_ASM
2334     static Section *last_text_section; /* to handle .previous asm directive */
2335     #endif
2336     /* bound check related sections */
2337     static Section *bounds_section; /* contains global data bound description */
2338     static Section *lbounds_section; /* contains local data bound description */
2339     /* symbol sections */
2340     static Section *symtab_section, *strtab_section;
2341     
2342     /* debug sections */
2343     static Section *stab_section, *stabstr_section;
2344     
2345     /* loc : local variable index
2346        ind : output code index
2347        rsym: return symbol
2348        anon_sym: anonymous symbol index
2349     */
2350     static long rsym, anon_sym, ind, loc;
2351     /* expression generation modifiers */
2352     static int const_wanted; /* true if constant wanted */
2353     static int nocode_wanted; /* true if no code generation wanted for an expression */
2354     static int global_expr;  /* true if compound literals must be allocated
2355                                 globally (used during initializers parsing */
2356     static CType func_vt; /* current function return type (used by return
2357                              instruction) */
2358     static int func_vc;
2359     static long last_line_num, last_ind, func_ind; /* debug last line number and pc */
2360     static int tok_ident;
2361     static TokenSym **table_ident;
2362     static TokenSym *hash_ident[TOK_HASH_SIZE];
2363     static char token_buf[STRING_MAX_SIZE + 1];
2364     static char *funcname;
2365     static Sym *global_stack, *local_stack;
2366     static Sym *define_stack;
2367     static Sym *global_label_stack, *local_label_stack;
2368     /* symbol allocator */
2369     #define SYM_POOL_NB (8192 / sizeof(Sym))
2370     static Sym *sym_free_first;
2371     
2372     static SValue vstack[VSTACK_SIZE], *vtop;
2373     /* some predefined types */
2374     static CType char_pointer_type, func_old_type, int_type;
2375     /* true if isid(c) || isnum(c) */
2376     static unsigned char isidnum_table[256];
2377     
2378     /* compile with debug symbol (and use them if error during execution) */
2379     static int do_debug = 0;
2380     
2381     /* compile with built-in memory and bounds checker */
2382     static int do_bounds_check = 0;
2383     
2384     /* display benchmark infos */
2385     #if !defined(LIBTCC)
2386     static int do_bench = 0;
2387     #endif
2388     static int total_lines;
2389     static int total_bytes;
2390     
2391     /* use GNU C extensions */
2392     static int gnu_ext = 1;
2393     
2394     /* use Tiny C extensions */
2395     static int tcc_ext = 1;
2396     
2397     /* max number of callers shown if error */
2398     static int num_callers = 6;
2399     static const char **rt_bound_error_msg;
2400     
2401     /* XXX: get rid of this ASAP */
2402     static struct TCCState *tcc_state;
2403     
2404     /* give the path of the tcc libraries */
2405     static const char *tcc_lib_path = CONFIG_TCCDIR;
2406     
2407     struct TCCState {
2408         int output_type;
2409      
2410         BufferedFile **include_stack_ptr;
2411         int *ifdef_stack_ptr;
2412     
2413         /* include file handling */
2414         char **include_paths;
2415         int nb_include_paths;
2416         char **sysinclude_paths;
2417         int nb_sysinclude_paths;
2418         CachedInclude **cached_includes;
2419         int nb_cached_includes;
2420     
2421         char **library_paths;
2422         int nb_library_paths;
2423     
2424         /* array of all loaded dlls (including those referenced by loaded
2425            dlls) */
2426         DLLReference **loaded_dlls;
2427         int nb_loaded_dlls;
2428     
2429         /* sections */
2430         Section **sections;
2431         int nb_sections; /* number of sections, including first dummy section */
2432     
2433         /* got handling */
2434         Section *got;
2435         Section *plt;
2436         unsigned long *got_offsets;
2437         int nb_got_offsets;
2438         /* give the correspondance from symtab indexes to dynsym indexes */
2439         int *symtab_to_dynsym;
2440     
2441         /* temporary dynamic symbol sections (for dll loading) */
2442         Section *dynsymtab_section;
2443         /* exported dynamic symbol section */
2444         Section *dynsym;
2445     
2446         int nostdinc; /* if true, no standard headers are added */
2447         int nostdlib; /* if true, no standard libraries are added */
2448     
2449         int nocommon; /* if true, do not use common symbols for .bss data */
2450     
2451         /* if true, static linking is performed */
2452         int static_link;
2453     
2454         /* if true, all symbols are exported */
2455         int rdynamic;
2456     
2457         /* if true, only link in referenced objects from archive */
2458         int alacarte_link;
2459     
2460         /* address of text section */
2461         unsigned long text_addr;
2462         int has_text_addr;
2463         
2464         /* output format, see TCC_OUTPUT_FORMAT_xxx */
2465         int output_format;
2466     
2467         /* C language options */
2468         int char_is_unsigned;
2469         int leading_underscore;
2470         
2471         /* warning switches */
2472         int warn_write_strings;
2473         int warn_unsupported;
2474         int warn_error;
2475         int warn_none;
2476         int warn_implicit_function_declaration;
2477     
2478         /* error handling */
2479         void *error_opaque;
2480         void (*error_func)(void *opaque, const char *msg);
2481         int error_set_jmp_enabled;
2482         jmp_buf error_jmp_buf;
2483         int nb_errors;
2484     
2485         /* tiny assembler state */
2486         Sym *asm_labels;
2487     
2488         /* see include_stack_ptr */
2489         BufferedFile *include_stack[INCLUDE_STACK_SIZE];
2490     
2491         /* see ifdef_stack_ptr */
2492         int ifdef_stack[IFDEF_STACK_SIZE];
2493     
2494         /* see cached_includes */
2495         int cached_includes_hash[CACHED_INCLUDES_HASH_SIZE];
2496     
2497         /* pack stack */
2498         int pack_stack[PACK_STACK_SIZE];
2499         int *pack_stack_ptr;
2500     };
2501     
2502     /* The current value can be: */
2503     #define VT_VALMASK   0x00ff
2504     #define VT_CONST     0x00f0  /* constant in vc 
2505                                   (must be first non register value) */
2506     #define VT_LLOCAL    0x00f1  /* lvalue, offset on stack */
2507     #define VT_LOCAL     0x00f2  /* offset on stack */
2508     #define VT_CMP       0x00f3  /* the value is stored in processor flags (in vc) */
2509     #define VT_JMP       0x00f4  /* value is the consequence of jmp true (even) */
2510     #define VT_JMPI      0x00f5  /* value is the consequence of jmp false (odd) */
2511     #define VT_LVAL      0x0100  /* var is an lvalue */
2512     #define VT_SYM       0x0200  /* a symbol value is added */
2513     #define VT_MUSTCAST  0x0400  /* value must be casted to be correct (used for
2514                                     char/short stored in integer registers) */
2515     #define VT_MUSTBOUND 0x0800  /* bound checking must be done before
2516                                     dereferencing value */
2517     #define VT_BOUNDED   0x8000  /* value is bounded. The address of the
2518                                     bounding function call point is in vc */
2519     #define VT_LVAL_BYTE     0x1000  /* lvalue is a byte */
2520     #define VT_LVAL_SHORT    0x2000  /* lvalue is a short */
2521     #define VT_LVAL_UNSIGNED 0x4000  /* lvalue is unsigned */
2522     #define VT_LVAL_TYPE     (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
2523     
2524     /* types */
2525     #define VT_INT        0  /* integer type */
2526     #define VT_BYTE       1  /* signed byte type */
2527     #define VT_SHORT      2  /* short type */
2528     #define VT_VOID       3  /* void type */
2529     #define VT_PTR        4  /* pointer */
2530     #define VT_ENUM       5  /* enum definition */
2531     #define VT_FUNC       6  /* function type */
2532     #define VT_STRUCT     7  /* struct/union definition */
2533     #define VT_FLOAT      8  /* IEEE float */
2534     #define VT_DOUBLE     9  /* IEEE double */
2535     #define VT_LDOUBLE   10  /* IEEE long double */
2536     #define VT_BOOL      11  /* ISOC99 boolean type */
2537     #define VT_LLONG     12  /* 64 bit integer */
2538     #define VT_LONG      13  /* long integer (NEVER USED as type, only
2539                                 during parsing) */
2540     #define VT_BTYPE      0x000f /* mask for basic type */
2541     #define VT_UNSIGNED   0x0010  /* unsigned type */
2542     #define VT_ARRAY      0x0020  /* array type (also has VT_PTR) */
2543     #define VT_BITFIELD   0x0040  /* bitfield modifier */
2544     #define VT_CONSTANT   0x0800  /* const modifier */
2545     #define VT_VOLATILE   0x1000  /* volatile modifier */
2546     #define VT_SIGNED     0x2000  /* signed type */
2547     
2548     /* storage */
2549     #define VT_EXTERN  0x00000080  /* extern definition */
2550     #define VT_STATIC  0x00000100  /* static variable */
2551     #define VT_TYPEDEF 0x00000200  /* typedef definition */
2552     #define VT_INLINE  0x00000400  /* inline definition */
2553     
2554     #define VT_STRUCT_SHIFT 16   /* shift for bitfield shift values */
2555     
2556     /* type mask (except storage) */
2557     #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
2558     #define VT_TYPE    (~(VT_STORAGE))
2559     
2560     /* token values */
2561     
2562     /* warning: the following compare tokens depend on i386 asm code */
2563     #define TOK_ULT 0x92
2564     #define TOK_UGE 0x93
2565     #define TOK_EQ  0x94
2566     #define TOK_NE  0x95
2567     #define TOK_ULE 0x96
2568     #define TOK_UGT 0x97
2569     #define TOK_LT  0x9c
2570     #define TOK_GE  0x9d
2571     #define TOK_LE  0x9e
2572     #define TOK_GT  0x9f
2573     
2574     #define TOK_LAND  0xa0
2575     #define TOK_LOR   0xa1
2576     
2577     #define TOK_DEC   0xa2
2578     #define TOK_MID   0xa3 /* inc/dec, to void constant */
2579     #define TOK_INC   0xa4
2580     #define TOK_UDIV  0xb0 /* unsigned division */
2581     #define TOK_UMOD  0xb1 /* unsigned modulo */
2582     #define TOK_PDIV  0xb2 /* fast division with undefined rounding for pointers */
2583     #define TOK_CINT   0xb3 /* number in tokc */
2584     #define TOK_CCHAR 0xb4 /* char constant in tokc */
2585     #define TOK_STR   0xb5 /* pointer to string in tokc */
2586     #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
2587     #define TOK_LCHAR    0xb7
2588     #define TOK_LSTR     0xb8
2589     #define TOK_CFLOAT   0xb9 /* float constant */
2590     #define TOK_LINENUM  0xba /* line number info */
2591     #define TOK_CDOUBLE  0xc0 /* double constant */
2592     #define TOK_CLDOUBLE 0xc1 /* long double constant */
2593     #define TOK_UMULL    0xc2 /* unsigned 32x32 -> 64 mul */
2594     #define TOK_ADDC1    0xc3 /* add with carry generation */
2595     #define TOK_ADDC2    0xc4 /* add with carry use */
2596     #define TOK_SUBC1    0xc5 /* add with carry generation */
2597     #define TOK_SUBC2    0xc6 /* add with carry use */
2598     #define TOK_CUINT    0xc8 /* unsigned int constant */
2599     #define TOK_CLLONG   0xc9 /* long long constant */
2600     #define TOK_CULLONG  0xca /* unsigned long long constant */
2601     #define TOK_ARROW    0xcb
2602     #define TOK_DOTS     0xcc /* three dots */
2603     #define TOK_SHR      0xcd /* unsigned shift right */
2604     #define TOK_PPNUM    0xce /* preprocessor number */
2605     
2606     #define TOK_SHL   0x01 /* shift left */
2607     #define TOK_SAR   0x02 /* signed shift right */
2608       
2609     /* assignement operators : normal operator or 0x80 */
2610     #define TOK_A_MOD 0xa5
2611     #define TOK_A_AND 0xa6
2612     #define TOK_A_MUL 0xaa
2613     #define TOK_A_ADD 0xab
2614     #define TOK_A_SUB 0xad
2615     #define TOK_A_DIV 0xaf
2616     #define TOK_A_XOR 0xde
2617     #define TOK_A_OR  0xfc
2618     #define TOK_A_SHL 0x81
2619     #define TOK_A_SAR 0x82
2620     
2621     #ifndef offsetof
2622     #define offsetof(type, field) ((size_t) &((type *)0)->field)
2623     #endif
2624     
2625     #ifndef countof
2626     #define countof(tab) (sizeof(tab) / sizeof((tab)[0]))
2627     #endif
2628     
2629     /* WARNING: the content of this string encodes token numbers */
2630     static char tok_two_chars[] = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
2631     
2632     #define TOK_EOF       (-1)  /* end of file */
2633     #define TOK_LINEFEED  10    /* line feed */
2634     
2635     /* all identificators and strings have token above that */
2636     #define TOK_IDENT 256
2637     
2638     /* only used for i386 asm opcodes definitions */
2639     #define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
2640     
2641     #define DEF_BWL(x) \
2642      DEF(TOK_ASM_ ## x ## b, #x "b") \
2643      DEF(TOK_ASM_ ## x ## w, #x "w") \
2644      DEF(TOK_ASM_ ## x ## l, #x "l") \
2645      DEF(TOK_ASM_ ## x, #x)
2646     
2647     #define DEF_WL(x) \
2648      DEF(TOK_ASM_ ## x ## w, #x "w") \
2649      DEF(TOK_ASM_ ## x ## l, #x "l") \
2650      DEF(TOK_ASM_ ## x, #x)
2651     
2652     #define DEF_FP1(x) \
2653      DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \
2654      DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
2655      DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
2656      DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")
2657     
2658     #define DEF_FP(x) \
2659      DEF(TOK_ASM_ ## f ## x, "f" #x ) \
2660      DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
2661      DEF_FP1(x)
2662     
2663     #define DEF_ASMTEST(x) \
2664      DEF_ASM(x ## o) \
2665      DEF_ASM(x ## no) \
2666      DEF_ASM(x ## b) \
2667      DEF_ASM(x ## c) \
2668      DEF_ASM(x ## nae) \
2669      DEF_ASM(x ## nb) \
2670      DEF_ASM(x ## nc) \
2671      DEF_ASM(x ## ae) \
2672      DEF_ASM(x ## e) \
2673      DEF_ASM(x ## z) \
2674      DEF_ASM(x ## ne) \
2675      DEF_ASM(x ## nz) \
2676      DEF_ASM(x ## be) \
2677      DEF_ASM(x ## na) \
2678      DEF_ASM(x ## nbe) \
2679      DEF_ASM(x ## a) \
2680      DEF_ASM(x ## s) \
2681      DEF_ASM(x ## ns) \
2682      DEF_ASM(x ## p) \
2683      DEF_ASM(x ## pe) \
2684      DEF_ASM(x ## np) \
2685      DEF_ASM(x ## po) \
2686      DEF_ASM(x ## l) \
2687      DEF_ASM(x ## nge) \
2688      DEF_ASM(x ## nl) \
2689      DEF_ASM(x ## ge) \
2690      DEF_ASM(x ## le) \
2691      DEF_ASM(x ## ng) \
2692      DEF_ASM(x ## nle) \
2693      DEF_ASM(x ## g)
2694     
2695     #define TOK_ASM_int TOK_INT
2696     
2697     enum tcc_token {
2698         TOK_LAST = TOK_IDENT - 1,
2699     #define DEF(id, str) id,
2700     // njn: inlined tcctok.h
2701     //#include "tcctok.h"
2702     //---------------------------------------------------------------------------
2703     /* keywords */
2704          DEF(TOK_INT, "int")
2705          DEF(TOK_VOID, "void")
2706          DEF(TOK_CHAR, "char")
2707          DEF(TOK_IF, "if")
2708          DEF(TOK_ELSE, "else")
2709          DEF(TOK_WHILE, "while")
2710          DEF(TOK_BREAK, "break")
2711          DEF(TOK_RETURN, "return")
2712          DEF(TOK_FOR, "for")
2713          DEF(TOK_EXTERN, "extern")
2714          DEF(TOK_STATIC, "static")
2715          DEF(TOK_UNSIGNED, "unsigned")
2716          DEF(TOK_GOTO, "goto")
2717          DEF(TOK_DO, "do")
2718          DEF(TOK_CONTINUE, "continue")
2719          DEF(TOK_SWITCH, "switch")
2720          DEF(TOK_CASE, "case")
2721     
2722          DEF(TOK_CONST1, "const")
2723          DEF(TOK_CONST2, "__const") /* gcc keyword */
2724          DEF(TOK_CONST3, "__const__") /* gcc keyword */
2725          DEF(TOK_VOLATILE1, "volatile")
2726          DEF(TOK_VOLATILE2, "__volatile") /* gcc keyword */
2727          DEF(TOK_VOLATILE3, "__volatile__") /* gcc keyword */
2728          DEF(TOK_LONG, "long")
2729          DEF(TOK_REGISTER, "register")
2730          DEF(TOK_SIGNED1, "signed")
2731          DEF(TOK_SIGNED2, "__signed") /* gcc keyword */
2732          DEF(TOK_SIGNED3, "__signed__") /* gcc keyword */
2733          DEF(TOK_AUTO, "auto")
2734          DEF(TOK_INLINE1, "inline")
2735          DEF(TOK_INLINE2, "__inline") /* gcc keyword */
2736          DEF(TOK_INLINE3, "__inline__") /* gcc keyword */
2737          DEF(TOK_RESTRICT1, "restrict")
2738          DEF(TOK_RESTRICT2, "__restrict")
2739          DEF(TOK_RESTRICT3, "__restrict__")
2740          DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */
2741          
2742          DEF(TOK_FLOAT, "float")
2743          DEF(TOK_DOUBLE, "double")
2744          DEF(TOK_BOOL, "_Bool")
2745          DEF(TOK_SHORT, "short")
2746          DEF(TOK_STRUCT, "struct")
2747          DEF(TOK_UNION, "union")
2748          DEF(TOK_TYPEDEF, "typedef")
2749          DEF(TOK_DEFAULT, "default")
2750          DEF(TOK_ENUM, "enum")
2751          DEF(TOK_SIZEOF, "sizeof")
2752          DEF(TOK_ATTRIBUTE1, "__attribute")
2753          DEF(TOK_ATTRIBUTE2, "__attribute__")
2754          DEF(TOK_ALIGNOF1, "__alignof")
2755          DEF(TOK_ALIGNOF2, "__alignof__")
2756          DEF(TOK_TYPEOF1, "typeof")
2757          DEF(TOK_TYPEOF2, "__typeof")
2758          DEF(TOK_TYPEOF3, "__typeof__")
2759          DEF(TOK_LABEL, "__label__")
2760          DEF(TOK_ASM1, "asm")
2761          DEF(TOK_ASM2, "__asm")
2762          DEF(TOK_ASM3, "__asm__")
2763     
2764     /*********************************************************************/
2765     /* the following are not keywords. They are included to ease parsing */
2766     /* preprocessor only */
2767          DEF(TOK_DEFINE, "define")
2768          DEF(TOK_INCLUDE, "include")
2769          DEF(TOK_INCLUDE_NEXT, "include_next")
2770          DEF(TOK_IFDEF, "ifdef")
2771          DEF(TOK_IFNDEF, "ifndef")
2772          DEF(TOK_ELIF, "elif")
2773          DEF(TOK_ENDIF, "endif")
2774          DEF(TOK_DEFINED, "defined")
2775          DEF(TOK_UNDEF, "undef")
2776          DEF(TOK_ERROR, "error")
2777          DEF(TOK_WARNING, "warning")
2778          DEF(TOK_LINE, "line")
2779          DEF(TOK_PRAGMA, "pragma")
2780          DEF(TOK___LINE__, "__LINE__")
2781          DEF(TOK___FILE__, "__FILE__")
2782          DEF(TOK___DATE__, "__DATE__")
2783          DEF(TOK___TIME__, "__TIME__")
2784          DEF(TOK___FUNCTION__, "__FUNCTION__")
2785          DEF(TOK___VA_ARGS__, "__VA_ARGS__")
2786          
2787     /* special identifiers */
2788          DEF(TOK___FUNC__, "__func__")
2789          
2790     /* attribute identifiers */
2791     /* XXX: handle all tokens generically since speed is not critical */
2792          DEF(TOK_SECTION1, "section")
2793          DEF(TOK_SECTION2, "__section__")
2794          DEF(TOK_ALIGNED1, "aligned")
2795          DEF(TOK_ALIGNED2, "__aligned__")
2796          DEF(TOK_PACKED1, "packed")
2797          DEF(TOK_PACKED2, "__packed__")
2798          DEF(TOK_UNUSED1, "unused")
2799          DEF(TOK_UNUSED2, "__unused__")
2800          DEF(TOK_CDECL1, "cdecl")
2801          DEF(TOK_CDECL2, "__cdecl")
2802          DEF(TOK_CDECL3, "__cdecl__")
2803          DEF(TOK_STDCALL1, "stdcall")
2804          DEF(TOK_STDCALL2, "__stdcall")
2805          DEF(TOK_STDCALL3, "__stdcall__")
2806          DEF(TOK_DLLEXPORT, "dllexport")
2807          DEF(TOK_NORETURN1, "noreturn")
2808          DEF(TOK_NORETURN2, "__noreturn__")
2809          DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")
2810          DEF(TOK_builtin_constant_p, "__builtin_constant_p")
2811          DEF(TOK_REGPARM1, "regparm")
2812          DEF(TOK_REGPARM2, "__regparm__")
2813     
2814     /* pragma */
2815          DEF(TOK_pack, "pack")
2816     #if !defined(TCC_TARGET_I386)
2817          /* already defined for assembler */
2818          DEF(TOK_ASM_push, "push")
2819          DEF(TOK_ASM_pop, "pop")
2820     #endif
2821     
2822     /* builtin functions or variables */
2823          DEF(TOK_memcpy, "memcpy")
2824          DEF(TOK_memset, "memset")
2825          DEF(TOK_alloca, "alloca")
2826          DEF(TOK___divdi3, "__divdi3")
2827          DEF(TOK___moddi3, "__moddi3")
2828          DEF(TOK___udivdi3, "__udivdi3")
2829          DEF(TOK___umoddi3, "__umoddi3")
2830     #if defined(TCC_TARGET_ARM)
2831          DEF(TOK___divsi3, "__divsi3")
2832          DEF(TOK___modsi3, "__modsi3")
2833          DEF(TOK___udivsi3, "__udivsi3")
2834          DEF(TOK___umodsi3, "__umodsi3")
2835          DEF(TOK___sardi3, "__ashrdi3")
2836          DEF(TOK___shrdi3, "__lshrdi3")
2837          DEF(TOK___shldi3, "__ashldi3")
2838          DEF(TOK___slltold, "__slltold")
2839          DEF(TOK___fixunssfsi, "__fixunssfsi")
2840          DEF(TOK___fixunsdfsi, "__fixunsdfsi")
2841          DEF(TOK___fixunsxfsi, "__fixunsxfsi")
2842          DEF(TOK___fixsfdi, "__fixsfdi")
2843          DEF(TOK___fixdfdi, "__fixdfdi")
2844          DEF(TOK___fixxfdi, "__fixxfdi")
2845     #elif defined(TCC_TARGET_C67)
2846          DEF(TOK__divi, "_divi")
2847          DEF(TOK__divu, "_divu")
2848          DEF(TOK__divf, "_divf")
2849          DEF(TOK__divd, "_divd")
2850          DEF(TOK__remi, "_remi")
2851          DEF(TOK__remu, "_remu")
2852          DEF(TOK___sardi3, "__sardi3")
2853          DEF(TOK___shrdi3, "__shrdi3")
2854          DEF(TOK___shldi3, "__shldi3")
2855     #else
2856          /* XXX: same names on i386 ? */
2857          DEF(TOK___sardi3, "__sardi3")
2858          DEF(TOK___shrdi3, "__shrdi3")
2859          DEF(TOK___shldi3, "__shldi3")
2860     #endif
2861          DEF(TOK___tcc_int_fpu_control, "__tcc_int_fpu_control")
2862          DEF(TOK___tcc_fpu_control, "__tcc_fpu_control")
2863          DEF(TOK___ulltof, "__ulltof")
2864          DEF(TOK___ulltod, "__ulltod")
2865          DEF(TOK___ulltold, "__ulltold")
2866          DEF(TOK___fixunssfdi, "__fixunssfdi")
2867          DEF(TOK___fixunsdfdi, "__fixunsdfdi")
2868          DEF(TOK___fixunsxfdi, "__fixunsxfdi")
2869          DEF(TOK___chkstk, "__chkstk")
2870     
2871     /* bound checking symbols */
2872     #ifdef CONFIG_TCC_BCHECK
2873          DEF(TOK___bound_ptr_add, "__bound_ptr_add")
2874          DEF(TOK___bound_ptr_indir1, "__bound_ptr_indir1")
2875          DEF(TOK___bound_ptr_indir2, "__bound_ptr_indir2")
2876          DEF(TOK___bound_ptr_indir4, "__bound_ptr_indir4")
2877          DEF(TOK___bound_ptr_indir8, "__bound_ptr_indir8")
2878          DEF(TOK___bound_ptr_indir12, "__bound_ptr_indir12")
2879          DEF(TOK___bound_ptr_indir16, "__bound_ptr_indir16")
2880          DEF(TOK___bound_local_new, "__bound_local_new")
2881          DEF(TOK___bound_local_delete, "__bound_local_delete")
2882          DEF(TOK_malloc, "malloc")
2883          DEF(TOK_free, "free")
2884          DEF(TOK_realloc, "realloc")
2885          DEF(TOK_memalign, "memalign")
2886          DEF(TOK_calloc, "calloc")
2887          DEF(TOK_memmove, "memmove")
2888          DEF(TOK_strlen, "strlen")
2889          DEF(TOK_strcpy, "strcpy")
2890     #endif
2891     
2892     /* Tiny Assembler */
2893     
2894      DEF_ASM(byte)
2895      DEF_ASM(align)
2896      DEF_ASM(skip)
2897      DEF_ASM(space)
2898      DEF_ASM(string)
2899      DEF_ASM(asciz)
2900      DEF_ASM(ascii)
2901      DEF_ASM(globl)
2902      DEF_ASM(global)
2903      DEF_ASM(text)
2904      DEF_ASM(data)
2905      DEF_ASM(bss)
2906      DEF_ASM(previous)
2907      DEF_ASM(fill)
2908      DEF_ASM(org)
2909      DEF_ASM(quad)
2910     
2911     #ifdef TCC_TARGET_I386
2912     
2913     /* WARNING: relative order of tokens is important. */
2914      DEF_ASM(al)
2915      DEF_ASM(cl)
2916      DEF_ASM(dl)
2917      DEF_ASM(bl)
2918      DEF_ASM(ah)
2919      DEF_ASM(ch)
2920      DEF_ASM(dh)
2921      DEF_ASM(bh)
2922      DEF_ASM(ax)
2923      DEF_ASM(cx)
2924      DEF_ASM(dx)
2925      DEF_ASM(bx)
2926      DEF_ASM(sp)
2927      DEF_ASM(bp)
2928      DEF_ASM(si)
2929      DEF_ASM(di)
2930      DEF_ASM(eax)
2931      DEF_ASM(ecx)
2932      DEF_ASM(edx)
2933      DEF_ASM(ebx)
2934      DEF_ASM(esp)
2935      DEF_ASM(ebp)
2936      DEF_ASM(esi)
2937      DEF_ASM(edi)
2938      DEF_ASM(mm0)
2939      DEF_ASM(mm1)
2940      DEF_ASM(mm2)
2941      DEF_ASM(mm3)
2942      DEF_ASM(mm4)
2943      DEF_ASM(mm5)
2944      DEF_ASM(mm6)
2945      DEF_ASM(mm7)
2946      DEF_ASM(xmm0)
2947      DEF_ASM(xmm1)
2948      DEF_ASM(xmm2)
2949      DEF_ASM(xmm3)
2950      DEF_ASM(xmm4)
2951      DEF_ASM(xmm5)
2952      DEF_ASM(xmm6)
2953      DEF_ASM(xmm7)
2954      DEF_ASM(cr0)
2955      DEF_ASM(cr1)
2956      DEF_ASM(cr2)
2957      DEF_ASM(cr3)
2958      DEF_ASM(cr4)
2959      DEF_ASM(cr5)
2960      DEF_ASM(cr6)
2961      DEF_ASM(cr7)
2962      DEF_ASM(tr0)
2963      DEF_ASM(tr1)
2964      DEF_ASM(tr2)
2965      DEF_ASM(tr3)
2966      DEF_ASM(tr4)
2967      DEF_ASM(tr5)
2968      DEF_ASM(tr6)
2969      DEF_ASM(tr7)
2970      DEF_ASM(db0)
2971      DEF_ASM(db1)
2972      DEF_ASM(db2)
2973      DEF_ASM(db3)
2974      DEF_ASM(db4)
2975      DEF_ASM(db5)
2976      DEF_ASM(db6)
2977      DEF_ASM(db7)
2978      DEF_ASM(dr0)
2979      DEF_ASM(dr1)
2980      DEF_ASM(dr2)
2981      DEF_ASM(dr3)
2982      DEF_ASM(dr4)
2983      DEF_ASM(dr5)
2984      DEF_ASM(dr6)
2985      DEF_ASM(dr7)
2986      DEF_ASM(es)
2987      DEF_ASM(cs)
2988      DEF_ASM(ss)
2989      DEF_ASM(ds)
2990      DEF_ASM(fs)
2991      DEF_ASM(gs)
2992      DEF_ASM(st)
2993     
2994      DEF_BWL(mov)
2995     
2996      /* generic two operands */
2997      DEF_BWL(add)
2998      DEF_BWL(or)
2999      DEF_BWL(adc)
3000      DEF_BWL(sbb)
3001      DEF_BWL(and)
3002      DEF_BWL(sub)
3003      DEF_BWL(xor)
3004      DEF_BWL(cmp)
3005     
3006      /* unary ops */
3007      DEF_BWL(inc)
3008      DEF_BWL(dec)
3009      DEF_BWL(not)
3010      DEF_BWL(neg)
3011      DEF_BWL(mul)
3012      DEF_BWL(imul)
3013      DEF_BWL(div)
3014      DEF_BWL(idiv)
3015     
3016      DEF_BWL(xchg)
3017      DEF_BWL(test)
3018     
3019      /* shifts */
3020      DEF_BWL(rol)
3021      DEF_BWL(ror)
3022      DEF_BWL(rcl)
3023      DEF_BWL(rcr)
3024      DEF_BWL(shl)
3025      DEF_BWL(shr)
3026      DEF_BWL(sar)
3027     
3028      DEF_ASM(shldw)
3029      DEF_ASM(shldl)
3030      DEF_ASM(shld)
3031      DEF_ASM(shrdw)
3032      DEF_ASM(shrdl)
3033      DEF_ASM(shrd)
3034     
3035      DEF_ASM(pushw)
3036      DEF_ASM(pushl)
3037      DEF_ASM(push)
3038      DEF_ASM(popw)
3039      DEF_ASM(popl)
3040      DEF_ASM(pop)
3041      DEF_BWL(in)
3042      DEF_BWL(out)
3043     
3044      DEF_WL(movzb)
3045     
3046      DEF_ASM(movzwl)
3047      DEF_ASM(movsbw)
3048      DEF_ASM(movsbl)
3049      DEF_ASM(movswl)
3050     
3051      DEF_WL(lea) 
3052     
3053      DEF_ASM(les) 
3054      DEF_ASM(lds) 
3055      DEF_ASM(lss) 
3056      DEF_ASM(lfs) 
3057      DEF_ASM(lgs) 
3058     
3059      DEF_ASM(call)
3060      DEF_ASM(jmp)
3061      DEF_ASM(lcall)
3062      DEF_ASM(ljmp)
3063      
3064      DEF_ASMTEST(j)
3065     
3066      DEF_ASMTEST(set)
3067      DEF_ASMTEST(cmov)
3068     
3069      DEF_WL(bsf)
3070      DEF_WL(bsr)
3071      DEF_WL(bt)
3072      DEF_WL(bts)
3073      DEF_WL(btr)
3074      DEF_WL(btc)
3075     
3076      DEF_WL(lsl)
3077     
3078      /* generic FP ops */
3079      DEF_FP(add)
3080      DEF_FP(mul)
3081     
3082      DEF_ASM(fcom)
3083      DEF_ASM(fcom_1) /* non existant op, just to have a regular table */
3084      DEF_FP1(com)
3085     
3086      DEF_FP(comp)
3087      DEF_FP(sub)
3088      DEF_FP(subr)
3089      DEF_FP(div)
3090      DEF_FP(divr)
3091     
3092      DEF_BWL(xadd)
3093      DEF_BWL(cmpxchg)
3094     
3095      /* string ops */
3096      DEF_BWL(cmps)
3097      DEF_BWL(scmp)
3098      DEF_BWL(ins)
3099      DEF_BWL(outs)
3100      DEF_BWL(lods)
3101      DEF_BWL(slod)
3102      DEF_BWL(movs)
3103      DEF_BWL(smov)
3104      DEF_BWL(scas)
3105      DEF_BWL(ssca)
3106      DEF_BWL(stos)
3107      DEF_BWL(ssto)
3108     
3109      /* generic asm ops */
3110     
3111     #define ALT(x)
3112     #define DEF_ASM_OP0(name, opcode) DEF_ASM(name)
3113     #define DEF_ASM_OP0L(name, opcode, group, instr_type)
3114     #define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
3115     #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
3116     #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
3117     // njn: inlined i386-asm.h
3118     //#include "i386-asm.h"
3119     //---------------------------------------------------------------------------
3120          DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
3121          DEF_ASM_OP0(popa, 0x61)
3122          DEF_ASM_OP0(clc, 0xf8)
3123          DEF_ASM_OP0(cld, 0xfc)
3124          DEF_ASM_OP0(cli, 0xfa)
3125          DEF_ASM_OP0(clts, 0x0f06)
3126          DEF_ASM_OP0(cmc, 0xf5)
3127          DEF_ASM_OP0(lahf, 0x9f)
3128          DEF_ASM_OP0(sahf, 0x9e)
3129          DEF_ASM_OP0(pushfl, 0x9c)
3130          DEF_ASM_OP0(popfl, 0x9d)
3131          DEF_ASM_OP0(pushf, 0x9c)
3132          DEF_ASM_OP0(popf, 0x9d)
3133          DEF_ASM_OP0(stc, 0xf9)
3134          DEF_ASM_OP0(std, 0xfd)
3135          DEF_ASM_OP0(sti, 0xfb)
3136          DEF_ASM_OP0(aaa, 0x37)
3137          DEF_ASM_OP0(aas, 0x3f)
3138          DEF_ASM_OP0(daa, 0x27)
3139          DEF_ASM_OP0(das, 0x2f)
3140          DEF_ASM_OP0(aad, 0xd50a)
3141          DEF_ASM_OP0(aam, 0xd40a)
3142          DEF_ASM_OP0(cbw, 0x6698)
3143          DEF_ASM_OP0(cwd, 0x6699)
3144          DEF_ASM_OP0(cwde, 0x98)
3145          DEF_ASM_OP0(cdq, 0x99)
3146          DEF_ASM_OP0(cbtw, 0x6698)
3147          DEF_ASM_OP0(cwtl, 0x98)
3148          DEF_ASM_OP0(cwtd, 0x6699)
3149          DEF_ASM_OP0(cltd, 0x99)
3150          DEF_ASM_OP0(int3, 0xcc)
3151          DEF_ASM_OP0(into, 0xce)
3152          DEF_ASM_OP0(iret, 0xcf)
3153          DEF_ASM_OP0(rsm, 0x0faa)
3154          DEF_ASM_OP0(hlt, 0xf4)
3155          DEF_ASM_OP0(wait, 0x9b)
3156          DEF_ASM_OP0(nop, 0x90)
3157          DEF_ASM_OP0(xlat, 0xd7)
3158     
3159          /* strings */
3160     ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
3161     ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
3162     
3163     ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
3164     ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
3165     
3166     ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
3167     ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
3168     
3169     ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
3170     ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
3171     
3172     ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
3173     ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
3174     
3175     ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
3176     ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
3177     
3178          /* bits */
3179          
3180     ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
3181     ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
3182     
3183     ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3184     ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3185     
3186     ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3187     ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3188     
3189     ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3190     ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3191     
3192     ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3193     ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3194     
3195          /* prefixes */
3196          DEF_ASM_OP0(aword, 0x67)
3197          DEF_ASM_OP0(addr16, 0x67)
3198          DEF_ASM_OP0(word, 0x66)
3199          DEF_ASM_OP0(data16, 0x66)
3200          DEF_ASM_OP0(lock, 0xf0)
3201          DEF_ASM_OP0(rep, 0xf3)
3202          DEF_ASM_OP0(repe, 0xf3)
3203          DEF_ASM_OP0(repz, 0xf3)
3204          DEF_ASM_OP0(repne, 0xf2)
3205          DEF_ASM_OP0(repnz, 0xf2)
3206                  
3207          DEF_ASM_OP0(invd, 0x0f08)
3208          DEF_ASM_OP0(wbinvd, 0x0f09)
3209          DEF_ASM_OP0(cpuid, 0x0fa2)
3210          DEF_ASM_OP0(wrmsr, 0x0f30)
3211          DEF_ASM_OP0(rdtsc, 0x0f31)
3212          DEF_ASM_OP0(rdmsr, 0x0f32)
3213          DEF_ASM_OP0(rdpmc, 0x0f33)
3214          DEF_ASM_OP0(ud2, 0x0f0b)
3215     
3216          /* NOTE: we took the same order as gas opcode definition order */
3217     ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
3218     ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
3219     ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3220     ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3221     ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
3222     ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
3223     
3224     ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
3225     ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
3226     
3227     ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
3228     ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
3229     ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
3230     ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
3231     ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
3232     ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
3233     
3234     ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
3235     ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
3236     ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
3237     ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
3238     ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
3239     
3240     ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
3241     ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
3242     ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
3243     ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
3244     ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
3245     
3246     ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
3247     ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
3248     ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
3249     
3250     ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
3251     ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
3252     ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3253     ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3254     
3255     ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
3256     ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
3257     ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
3258     ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
3259     
3260     ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
3261     ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
3262     ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
3263     ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
3264     
3265     ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
3266     
3267     ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3268     ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3269     ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3270     ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3271     ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3272     
3273          /* arith */
3274     ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
3275     ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3276     ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
3277     ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
3278     ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
3279     
3280     ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3281     ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3282     ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
3283     ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
3284     
3285     ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
3286     ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3287     ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
3288     ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3289     
3290     ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3291     ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3292     
3293     ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3294     ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3295     
3296     ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
3297     ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
3298     ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
3299     ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
3300     ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
3301     
3302     ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3303     ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
3304     ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3305     ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
3306     
3307          /* shifts */
3308     ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
3309     ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
3310     ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
3311     
3312     ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
3313     ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
3314     ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
3315     ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
3316     ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
3317     ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
3318     
3319     ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
3320     ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
3321     ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
3322     ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
3323     
3324     ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
3325     ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
3326     ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
3327     ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
3328     
3329     ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
3330     ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
3331         DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
3332         DEF_ASM_OP0(leave, 0xc9)
3333         DEF_ASM_OP0(ret, 0xc3)
3334     ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
3335         DEF_ASM_OP0(lret, 0xcb)
3336     ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
3337     
3338     ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
3339         DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
3340         DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
3341         DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
3342         DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
3343         DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
3344         DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
3345          
3346          /* float */
3347          /* specific fcomp handling */
3348     ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
3349     
3350     ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
3351     ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
3352     ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
3353     ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
3354     ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
3355     ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
3356     ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
3357     ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3358     ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3359     ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3360     ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3361     
3362          DEF_ASM_OP0(fucompp, 0xdae9)
3363          DEF_ASM_OP0(ftst, 0xd9e4)
3364          DEF_ASM_OP0(fxam, 0xd9e5)
3365          DEF_ASM_OP0(fld1, 0xd9e8)
3366          DEF_ASM_OP0(fldl2t, 0xd9e9)
3367          DEF_ASM_OP0(fldl2e, 0xd9ea)
3368          DEF_ASM_OP0(fldpi, 0xd9eb)
3369          DEF_ASM_OP0(fldlg2, 0xd9ec)
3370          DEF_ASM_OP0(fldln2, 0xd9ed)
3371          DEF_ASM_OP0(fldz, 0xd9ee)
3372     
3373          DEF_ASM_OP0(f2xm1, 0xd9f0)
3374          DEF_ASM_OP0(fyl2x, 0xd9f1)
3375          DEF_ASM_OP0(fptan, 0xd9f2)
3376          DEF_ASM_OP0(fpatan, 0xd9f3)
3377          DEF_ASM_OP0(fxtract, 0xd9f4)
3378          DEF_ASM_OP0(fprem1, 0xd9f5)
3379          DEF_ASM_OP0(fdecstp, 0xd9f6)
3380          DEF_ASM_OP0(fincstp, 0xd9f7)
3381          DEF_ASM_OP0(fprem, 0xd9f8)
3382          DEF_ASM_OP0(fyl2xp1, 0xd9f9)
3383          DEF_ASM_OP0(fsqrt, 0xd9fa)
3384          DEF_ASM_OP0(fsincos, 0xd9fb)
3385          DEF_ASM_OP0(frndint, 0xd9fc)
3386          DEF_ASM_OP0(fscale, 0xd9fd)
3387          DEF_ASM_OP0(fsin, 0xd9fe)
3388          DEF_ASM_OP0(fcos, 0xd9ff)
3389          DEF_ASM_OP0(fchs, 0xd9e0)
3390          DEF_ASM_OP0(fabs, 0xd9e1)
3391          DEF_ASM_OP0(fninit, 0xdbe3)
3392          DEF_ASM_OP0(fnclex, 0xdbe2)
3393          DEF_ASM_OP0(fnop, 0xd9d0)
3394          DEF_ASM_OP0(fwait, 0x9b)
3395     
3396         /* fp load */
3397         DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
3398         DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
3399         DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
3400     ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
3401         DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
3402         DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
3403         DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
3404         DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
3405         DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
3406         
3407         /* fp store */
3408         DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
3409         DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
3410         DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
3411         DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
3412     ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
3413         DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
3414         DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
3415         DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
3416         DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
3417         DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
3418     
3419         DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
3420         DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
3421         DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
3422         DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
3423         DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
3424     
3425         /* exchange */
3426         DEF_ASM_OP0(fxch, 0xd9c9)
3427     ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
3428     
3429         /* misc FPU */
3430         DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
3431         DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
3432     
3433         DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
3434         DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
3435         DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
3436         DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
3437         DEF_ASM_OP0(fnstsw, 0xdfe0)
3438     ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
3439     ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
3440         DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
3441     ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
3442     ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
3443         DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
3444         DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
3445         DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
3446         DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
3447         DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
3448         DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
3449         DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
3450         DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
3451         DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
3452         DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
3453         DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
3454     
3455         /* segments */
3456         DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
3457         DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
3458         DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
3459         DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
3460         DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
3461         DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
3462     ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
3463         DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
3464         DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
3465         DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
3466         DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
3467         DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
3468         DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
3469         DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
3470         DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
3471     
3472         /* 486 */
3473         DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
3474     ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
3475     ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
3476         DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
3477     
3478         DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
3479         DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
3480     
3481         /* pentium */
3482         DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
3483         
3484         /* pentium pro */
3485         ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
3486     
3487         DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3488         DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3489         DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3490         DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3491         DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3492         DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3493         DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3494         DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3495     
3496         DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3497         DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3498         DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3499         DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3500     
3501         /* mmx */
3502         DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
3503         DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
3504     ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
3505         DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3506     ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
3507         DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3508         DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3509         DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3510         DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3511         DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3512         DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3513         DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3514         DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3515         DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3516         DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3517         DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3518         DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3519         DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3520         DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3521         DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3522         DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3523         DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3524         DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3525         DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3526         DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3527         DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3528         DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3529         DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3530     ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
3531         DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3532     ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
3533         DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3534     ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
3535         DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3536     ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
3537         DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3538     ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
3539         DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3540     ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
3541         DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3542     ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
3543         DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3544     ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
3545         DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3546         DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3547         DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3548         DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3549         DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3550         DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3551         DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3552         DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3553         DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3554         DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3555         DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3556         DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3557         DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3558         DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3559     
3560     #undef ALT
3561     #undef DEF_ASM_OP0
3562     #undef DEF_ASM_OP0L
3563     #undef DEF_ASM_OP1
3564     #undef DEF_ASM_OP2
3565     #undef DEF_ASM_OP3
3566     //---------------------------------------------------------------------------
3567     
3568     #define ALT(x)
3569     #define DEF_ASM_OP0(name, opcode)
3570     #define DEF_ASM_OP0L(name, opcode, group, instr_type) DEF_ASM(name)
3571     #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) DEF_ASM(name)
3572     #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) DEF_ASM(name)
3573     #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) DEF_ASM(name)
3574     // njn: inlined i386-asm.h
3575     //#include "i386-asm.h"
3576     //---------------------------------------------------------------------------
3577          DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
3578          DEF_ASM_OP0(popa, 0x61)
3579          DEF_ASM_OP0(clc, 0xf8)
3580          DEF_ASM_OP0(cld, 0xfc)
3581          DEF_ASM_OP0(cli, 0xfa)
3582          DEF_ASM_OP0(clts, 0x0f06)
3583          DEF_ASM_OP0(cmc, 0xf5)
3584          DEF_ASM_OP0(lahf, 0x9f)
3585          DEF_ASM_OP0(sahf, 0x9e)
3586          DEF_ASM_OP0(pushfl, 0x9c)
3587          DEF_ASM_OP0(popfl, 0x9d)
3588          DEF_ASM_OP0(pushf, 0x9c)
3589          DEF_ASM_OP0(popf, 0x9d)
3590          DEF_ASM_OP0(stc, 0xf9)
3591          DEF_ASM_OP0(std, 0xfd)
3592          DEF_ASM_OP0(sti, 0xfb)
3593          DEF_ASM_OP0(aaa, 0x37)
3594          DEF_ASM_OP0(aas, 0x3f)
3595          DEF_ASM_OP0(daa, 0x27)
3596          DEF_ASM_OP0(das, 0x2f)
3597          DEF_ASM_OP0(aad, 0xd50a)
3598          DEF_ASM_OP0(aam, 0xd40a)
3599          DEF_ASM_OP0(cbw, 0x6698)
3600          DEF_ASM_OP0(cwd, 0x6699)
3601          DEF_ASM_OP0(cwde, 0x98)
3602          DEF_ASM_OP0(cdq, 0x99)
3603          DEF_ASM_OP0(cbtw, 0x6698)
3604          DEF_ASM_OP0(cwtl, 0x98)
3605          DEF_ASM_OP0(cwtd, 0x6699)
3606          DEF_ASM_OP0(cltd, 0x99)
3607          DEF_ASM_OP0(int3, 0xcc)
3608          DEF_ASM_OP0(into, 0xce)
3609          DEF_ASM_OP0(iret, 0xcf)
3610          DEF_ASM_OP0(rsm, 0x0faa)
3611          DEF_ASM_OP0(hlt, 0xf4)
3612          DEF_ASM_OP0(wait, 0x9b)
3613          DEF_ASM_OP0(nop, 0x90)
3614          DEF_ASM_OP0(xlat, 0xd7)
3615     
3616          /* strings */
3617     ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
3618     ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
3619     
3620     ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
3621     ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
3622     
3623     ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
3624     ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
3625     
3626     ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
3627     ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
3628     
3629     ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
3630     ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
3631     
3632     ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
3633     ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
3634     
3635          /* bits */
3636          
3637     ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
3638     ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
3639     
3640     ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3641     ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3642     
3643     ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3644     ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3645     
3646     ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3647     ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3648     
3649     ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3650     ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3651     
3652          /* prefixes */
3653          DEF_ASM_OP0(aword, 0x67)
3654          DEF_ASM_OP0(addr16, 0x67)
3655          DEF_ASM_OP0(word, 0x66)
3656          DEF_ASM_OP0(data16, 0x66)
3657          DEF_ASM_OP0(lock, 0xf0)
3658          DEF_ASM_OP0(rep, 0xf3)
3659          DEF_ASM_OP0(repe, 0xf3)
3660          DEF_ASM_OP0(repz, 0xf3)
3661          DEF_ASM_OP0(repne, 0xf2)
3662          DEF_ASM_OP0(repnz, 0xf2)
3663                  
3664          DEF_ASM_OP0(invd, 0x0f08)
3665          DEF_ASM_OP0(wbinvd, 0x0f09)
3666          DEF_ASM_OP0(cpuid, 0x0fa2)
3667          DEF_ASM_OP0(wrmsr, 0x0f30)
3668          DEF_ASM_OP0(rdtsc, 0x0f31)
3669          DEF_ASM_OP0(rdmsr, 0x0f32)
3670          DEF_ASM_OP0(rdpmc, 0x0f33)
3671          DEF_ASM_OP0(ud2, 0x0f0b)
3672     
3673          /* NOTE: we took the same order as gas opcode definition order */
3674     ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
3675     ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
3676     ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3677     ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3678     ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
3679     ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
3680     
3681     ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
3682     ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
3683     
3684     ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
3685     ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
3686     ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
3687     ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
3688     ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
3689     ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
3690     
3691     ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
3692     ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
3693     ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
3694     ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
3695     ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
3696     
3697     ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
3698     ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
3699     ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
3700     ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
3701     ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
3702     
3703     ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
3704     ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
3705     ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
3706     
3707     ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
3708     ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
3709     ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3710     ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3711     
3712     ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
3713     ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
3714     ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
3715     ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
3716     
3717     ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
3718     ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
3719     ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
3720     ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
3721     
3722     ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
3723     
3724     ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3725     ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3726     ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3727     ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3728     ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3729     
3730          /* arith */
3731     ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
3732     ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3733     ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
3734     ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
3735     ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
3736     
3737     ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3738     ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3739     ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
3740     ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
3741     
3742     ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
3743     ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3744     ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
3745     ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3746     
3747     ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3748     ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3749     
3750     ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3751     ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3752     
3753     ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
3754     ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
3755     ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
3756     ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
3757     ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
3758     
3759     ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3760     ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
3761     ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3762     ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
3763     
3764          /* shifts */
3765     ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
3766     ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
3767     ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
3768     
3769     ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
3770     ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
3771     ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
3772     ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
3773     ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
3774     ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
3775     
3776     ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
3777     ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
3778     ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
3779     ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
3780     
3781     ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
3782     ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
3783     ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
3784     ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
3785     
3786     ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
3787     ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
3788         DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
3789         DEF_ASM_OP0(leave, 0xc9)
3790         DEF_ASM_OP0(ret, 0xc3)
3791     ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
3792         DEF_ASM_OP0(lret, 0xcb)
3793     ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
3794     
3795     ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
3796         DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
3797         DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
3798         DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
3799         DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
3800         DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
3801         DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
3802          
3803          /* float */
3804          /* specific fcomp handling */
3805     ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
3806     
3807     ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
3808     ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
3809     ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
3810     ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
3811     ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
3812     ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
3813     ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
3814     ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3815     ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3816     ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3817     ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3818     
3819          DEF_ASM_OP0(fucompp, 0xdae9)
3820          DEF_ASM_OP0(ftst, 0xd9e4)
3821          DEF_ASM_OP0(fxam, 0xd9e5)
3822          DEF_ASM_OP0(fld1, 0xd9e8)
3823          DEF_ASM_OP0(fldl2t, 0xd9e9)
3824          DEF_ASM_OP0(fldl2e, 0xd9ea)
3825          DEF_ASM_OP0(fldpi, 0xd9eb)
3826          DEF_ASM_OP0(fldlg2, 0xd9ec)
3827          DEF_ASM_OP0(fldln2, 0xd9ed)
3828          DEF_ASM_OP0(fldz, 0xd9ee)
3829     
3830          DEF_ASM_OP0(f2xm1, 0xd9f0)
3831          DEF_ASM_OP0(fyl2x, 0xd9f1)
3832          DEF_ASM_OP0(fptan, 0xd9f2)
3833          DEF_ASM_OP0(fpatan, 0xd9f3)
3834          DEF_ASM_OP0(fxtract, 0xd9f4)
3835          DEF_ASM_OP0(fprem1, 0xd9f5)
3836          DEF_ASM_OP0(fdecstp, 0xd9f6)
3837          DEF_ASM_OP0(fincstp, 0xd9f7)
3838          DEF_ASM_OP0(fprem, 0xd9f8)
3839          DEF_ASM_OP0(fyl2xp1, 0xd9f9)
3840          DEF_ASM_OP0(fsqrt, 0xd9fa)
3841          DEF_ASM_OP0(fsincos, 0xd9fb)
3842          DEF_ASM_OP0(frndint, 0xd9fc)
3843          DEF_ASM_OP0(fscale, 0xd9fd)
3844          DEF_ASM_OP0(fsin, 0xd9fe)
3845          DEF_ASM_OP0(fcos, 0xd9ff)
3846          DEF_ASM_OP0(fchs, 0xd9e0)
3847          DEF_ASM_OP0(fabs, 0xd9e1)
3848          DEF_ASM_OP0(fninit, 0xdbe3)
3849          DEF_ASM_OP0(fnclex, 0xdbe2)
3850          DEF_ASM_OP0(fnop, 0xd9d0)
3851          DEF_ASM_OP0(fwait, 0x9b)
3852     
3853         /* fp load */
3854         DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
3855         DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
3856         DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
3857     ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
3858         DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
3859         DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
3860         DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
3861         DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
3862         DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
3863         
3864         /* fp store */
3865         DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
3866         DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
3867         DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
3868         DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
3869     ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
3870         DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
3871         DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
3872         DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
3873         DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
3874         DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
3875     
3876         DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
3877         DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
3878         DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
3879         DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
3880         DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
3881     
3882         /* exchange */
3883         DEF_ASM_OP0(fxch, 0xd9c9)
3884     ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
3885     
3886         /* misc FPU */
3887         DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
3888         DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
3889     
3890         DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
3891         DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
3892         DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
3893         DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
3894         DEF_ASM_OP0(fnstsw, 0xdfe0)
3895     ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
3896     ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
3897         DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
3898     ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
3899     ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
3900         DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
3901         DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
3902         DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
3903         DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
3904         DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
3905         DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
3906         DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
3907         DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
3908         DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
3909         DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
3910         DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
3911     
3912         /* segments */
3913         DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
3914         DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
3915         DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
3916         DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
3917         DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
3918         DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
3919     ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
3920         DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
3921         DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
3922         DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
3923         DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
3924         DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
3925         DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
3926         DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
3927         DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
3928     
3929         /* 486 */
3930         DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
3931     ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
3932     ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
3933         DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
3934     
3935         DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
3936         DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
3937     
3938         /* pentium */
3939         DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
3940         
3941         /* pentium pro */
3942         ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
3943     
3944         DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3945         DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3946         DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3947         DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3948         DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3949         DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3950         DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3951         DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3952     
3953         DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3954         DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3955         DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3956         DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3957     
3958         /* mmx */
3959         DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
3960         DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
3961     ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
3962         DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3963     ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
3964         DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3965         DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3966         DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3967         DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3968         DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3969         DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3970         DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3971         DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3972         DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3973         DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3974         DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3975         DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3976         DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3977         DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3978         DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3979         DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3980         DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3981         DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3982         DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3983         DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3984         DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3985         DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3986         DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3987     ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
3988         DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3989     ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
3990         DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3991     ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
3992         DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3993     ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
3994         DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3995     ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
3996         DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3997     ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
3998         DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3999     ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
4000         DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4001     ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
4002         DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4003         DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4004         DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4005         DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4006         DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4007         DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4008         DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4009         DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4010         DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4011         DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4012         DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4013         DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4014         DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4015         DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4016     
4017     #undef ALT
4018     #undef DEF_ASM_OP0
4019     #undef DEF_ASM_OP0L
4020     #undef DEF_ASM_OP1
4021     #undef DEF_ASM_OP2
4022     #undef DEF_ASM_OP3
4023     //---------------------------------------------------------------------------
4024     
4025     #endif
4026     //---------------------------------------------------------------------------
4027     #undef DEF
4028     };
4029     
4030     static const char tcc_keywords[] = 
4031     #define DEF(id, str) str "\0"
4032     // njn: inlined tcctok.h
4033     //#include "tcctok.h"
4034     //---------------------------------------------------------------------------
4035     /* keywords */
4036          DEF(TOK_INT, "int")
4037          DEF(TOK_VOID, "void")
4038          DEF(TOK_CHAR, "char")
4039          DEF(TOK_IF, "if")
4040          DEF(TOK_ELSE, "else")
4041          DEF(TOK_WHILE, "while")
4042          DEF(TOK_BREAK, "break")
4043          DEF(TOK_RETURN, "return")
4044          DEF(TOK_FOR, "for")
4045          DEF(TOK_EXTERN, "extern")
4046          DEF(TOK_STATIC, "static")
4047          DEF(TOK_UNSIGNED, "unsigned")
4048          DEF(TOK_GOTO, "goto")
4049          DEF(TOK_DO, "do")
4050          DEF(TOK_CONTINUE, "continue")
4051          DEF(TOK_SWITCH, "switch")
4052          DEF(TOK_CASE, "case")
4053     
4054          DEF(TOK_CONST1, "const")
4055          DEF(TOK_CONST2, "__const") /* gcc keyword */
4056          DEF(TOK_CONST3, "__const__") /* gcc keyword */
4057          DEF(TOK_VOLATILE1, "volatile")
4058          DEF(TOK_VOLATILE2, "__volatile") /* gcc keyword */
4059          DEF(TOK_VOLATILE3, "__volatile__") /* gcc keyword */
4060          DEF(TOK_LONG, "long")
4061          DEF(TOK_REGISTER, "register")
4062          DEF(TOK_SIGNED1, "signed")
4063          DEF(TOK_SIGNED2, "__signed") /* gcc keyword */
4064          DEF(TOK_SIGNED3, "__signed__") /* gcc keyword */
4065          DEF(TOK_AUTO, "auto")
4066          DEF(TOK_INLINE1, "inline")
4067          DEF(TOK_INLINE2, "__inline") /* gcc keyword */
4068          DEF(TOK_INLINE3, "__inline__") /* gcc keyword */
4069          DEF(TOK_RESTRICT1, "restrict")
4070          DEF(TOK_RESTRICT2, "__restrict")
4071          DEF(TOK_RESTRICT3, "__restrict__")
4072          DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */
4073          
4074          DEF(TOK_FLOAT, "float")
4075          DEF(TOK_DOUBLE, "double")
4076          DEF(TOK_BOOL, "_Bool")
4077          DEF(TOK_SHORT, "short")
4078          DEF(TOK_STRUCT, "struct")
4079          DEF(TOK_UNION, "union")
4080          DEF(TOK_TYPEDEF, "typedef")
4081          DEF(TOK_DEFAULT, "default")
4082          DEF(TOK_ENUM, "enum")
4083          DEF(TOK_SIZEOF, "sizeof")
4084          DEF(TOK_ATTRIBUTE1, "__attribute")
4085          DEF(TOK_ATTRIBUTE2, "__attribute__")
4086          DEF(TOK_ALIGNOF1, "__alignof")
4087          DEF(TOK_ALIGNOF2, "__alignof__")
4088          DEF(TOK_TYPEOF1, "typeof")
4089          DEF(TOK_TYPEOF2, "__typeof")
4090          DEF(TOK_TYPEOF3, "__typeof__")
4091          DEF(TOK_LABEL, "__label__")
4092          DEF(TOK_ASM1, "asm")
4093          DEF(TOK_ASM2, "__asm")
4094          DEF(TOK_ASM3, "__asm__")
4095     
4096     /*********************************************************************/
4097     /* the following are not keywords. They are included to ease parsing */
4098     /* preprocessor only */
4099          DEF(TOK_DEFINE, "define")
4100          DEF(TOK_INCLUDE, "include")
4101          DEF(TOK_INCLUDE_NEXT, "include_next")
4102          DEF(TOK_IFDEF, "ifdef")
4103          DEF(TOK_IFNDEF, "ifndef")
4104          DEF(TOK_ELIF, "elif")
4105          DEF(TOK_ENDIF, "endif")
4106          DEF(TOK_DEFINED, "defined")
4107          DEF(TOK_UNDEF, "undef")
4108          DEF(TOK_ERROR, "error")
4109          DEF(TOK_WARNING, "warning")
4110          DEF(TOK_LINE, "line")
4111          DEF(TOK_PRAGMA, "pragma")
4112          DEF(TOK___LINE__, "__LINE__")
4113          DEF(TOK___FILE__, "__FILE__")
4114          DEF(TOK___DATE__, "__DATE__")
4115          DEF(TOK___TIME__, "__TIME__")
4116          DEF(TOK___FUNCTION__, "__FUNCTION__")
4117          DEF(TOK___VA_ARGS__, "__VA_ARGS__")
4118          
4119     /* special identifiers */
4120          DEF(TOK___FUNC__, "__func__")
4121          
4122     /* attribute identifiers */
4123     /* XXX: handle all tokens generically since speed is not critical */
4124          DEF(TOK_SECTION1, "section")
4125          DEF(TOK_SECTION2, "__section__")
4126          DEF(TOK_ALIGNED1, "aligned")
4127          DEF(TOK_ALIGNED2, "__aligned__")
4128          DEF(TOK_PACKED1, "packed")
4129          DEF(TOK_PACKED2, "__packed__")
4130          DEF(TOK_UNUSED1, "unused")
4131          DEF(TOK_UNUSED2, "__unused__")
4132          DEF(TOK_CDECL1, "cdecl")
4133          DEF(TOK_CDECL2, "__cdecl")
4134          DEF(TOK_CDECL3, "__cdecl__")
4135          DEF(TOK_STDCALL1, "stdcall")
4136          DEF(TOK_STDCALL2, "__stdcall")
4137          DEF(TOK_STDCALL3, "__stdcall__")
4138          DEF(TOK_DLLEXPORT, "dllexport")
4139          DEF(TOK_NORETURN1, "noreturn")
4140          DEF(TOK_NORETURN2, "__noreturn__")
4141          DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")
4142          DEF(TOK_builtin_constant_p, "__builtin_constant_p")
4143          DEF(TOK_REGPARM1, "regparm")
4144          DEF(TOK_REGPARM2, "__regparm__")
4145     
4146     /* pragma */
4147          DEF(TOK_pack, "pack")
4148     #if !defined(TCC_TARGET_I386)
4149          /* already defined for assembler */
4150          DEF(TOK_ASM_push, "push")
4151          DEF(TOK_ASM_pop, "pop")
4152     #endif
4153     
4154     /* builtin functions or variables */
4155          DEF(TOK_memcpy, "memcpy")
4156          DEF(TOK_memset, "memset")
4157          DEF(TOK_alloca, "alloca")
4158          DEF(TOK___divdi3, "__divdi3")
4159          DEF(TOK___moddi3, "__moddi3")
4160          DEF(TOK___udivdi3, "__udivdi3")
4161          DEF(TOK___umoddi3, "__umoddi3")
4162     #if defined(TCC_TARGET_ARM)
4163          DEF(TOK___divsi3, "__divsi3")
4164          DEF(TOK___modsi3, "__modsi3")
4165          DEF(TOK___udivsi3, "__udivsi3")
4166          DEF(TOK___umodsi3, "__umodsi3")
4167          DEF(TOK___sardi3, "__ashrdi3")
4168          DEF(TOK___shrdi3, "__lshrdi3")
4169          DEF(TOK___shldi3, "__ashldi3")
4170          DEF(TOK___slltold, "__slltold")
4171          DEF(TOK___fixunssfsi, "__fixunssfsi")
4172          DEF(TOK___fixunsdfsi, "__fixunsdfsi")
4173          DEF(TOK___fixunsxfsi, "__fixunsxfsi")
4174          DEF(TOK___fixsfdi, "__fixsfdi")
4175          DEF(TOK___fixdfdi, "__fixdfdi")
4176          DEF(TOK___fixxfdi, "__fixxfdi")
4177     #elif defined(TCC_TARGET_C67)
4178          DEF(TOK__divi, "_divi")
4179          DEF(TOK__divu, "_divu")
4180          DEF(TOK__divf, "_divf")
4181          DEF(TOK__divd, "_divd")
4182          DEF(TOK__remi, "_remi")
4183          DEF(TOK__remu, "_remu")
4184          DEF(TOK___sardi3, "__sardi3")
4185          DEF(TOK___shrdi3, "__shrdi3")
4186          DEF(TOK___shldi3, "__shldi3")
4187     #else
4188          /* XXX: same names on i386 ? */
4189          DEF(TOK___sardi3, "__sardi3")
4190          DEF(TOK___shrdi3, "__shrdi3")
4191          DEF(TOK___shldi3, "__shldi3")
4192     #endif
4193          DEF(TOK___tcc_int_fpu_control, "__tcc_int_fpu_control")
4194          DEF(TOK___tcc_fpu_control, "__tcc_fpu_control")
4195          DEF(TOK___ulltof, "__ulltof")
4196          DEF(TOK___ulltod, "__ulltod")
4197          DEF(TOK___ulltold, "__ulltold")
4198          DEF(TOK___fixunssfdi, "__fixunssfdi")
4199          DEF(TOK___fixunsdfdi, "__fixunsdfdi")
4200          DEF(TOK___fixunsxfdi, "__fixunsxfdi")
4201          DEF(TOK___chkstk, "__chkstk")
4202     
4203     /* bound checking symbols */
4204     #ifdef CONFIG_TCC_BCHECK
4205          DEF(TOK___bound_ptr_add, "__bound_ptr_add")
4206          DEF(TOK___bound_ptr_indir1, "__bound_ptr_indir1")
4207          DEF(TOK___bound_ptr_indir2, "__bound_ptr_indir2")
4208          DEF(TOK___bound_ptr_indir4, "__bound_ptr_indir4")
4209          DEF(TOK___bound_ptr_indir8, "__bound_ptr_indir8")
4210          DEF(TOK___bound_ptr_indir12, "__bound_ptr_indir12")
4211          DEF(TOK___bound_ptr_indir16, "__bound_ptr_indir16")
4212          DEF(TOK___bound_local_new, "__bound_local_new")
4213          DEF(TOK___bound_local_delete, "__bound_local_delete")
4214          DEF(TOK_malloc, "malloc")
4215          DEF(TOK_free, "free")
4216          DEF(TOK_realloc, "realloc")
4217          DEF(TOK_memalign, "memalign")
4218          DEF(TOK_calloc, "calloc")
4219          DEF(TOK_memmove, "memmove")
4220          DEF(TOK_strlen, "strlen")
4221          DEF(TOK_strcpy, "strcpy")
4222     #endif
4223     
4224     /* Tiny Assembler */
4225     
4226      DEF_ASM(byte)
4227      DEF_ASM(align)
4228      DEF_ASM(skip)
4229      DEF_ASM(space)
4230      DEF_ASM(string)
4231      DEF_ASM(asciz)
4232      DEF_ASM(ascii)
4233      DEF_ASM(globl)
4234      DEF_ASM(global)
4235      DEF_ASM(text)
4236      DEF_ASM(data)
4237      DEF_ASM(bss)
4238      DEF_ASM(previous)
4239      DEF_ASM(fill)
4240      DEF_ASM(org)
4241      DEF_ASM(quad)
4242     
4243     #ifdef TCC_TARGET_I386
4244     
4245     /* WARNING: relative order of tokens is important. */
4246      DEF_ASM(al)
4247      DEF_ASM(cl)
4248      DEF_ASM(dl)
4249      DEF_ASM(bl)
4250      DEF_ASM(ah)
4251      DEF_ASM(ch)
4252      DEF_ASM(dh)
4253      DEF_ASM(bh)
4254      DEF_ASM(ax)
4255      DEF_ASM(cx)
4256      DEF_ASM(dx)
4257      DEF_ASM(bx)
4258      DEF_ASM(sp)
4259      DEF_ASM(bp)
4260      DEF_ASM(si)
4261      DEF_ASM(di)
4262      DEF_ASM(eax)
4263      DEF_ASM(ecx)
4264      DEF_ASM(edx)
4265      DEF_ASM(ebx)
4266      DEF_ASM(esp)
4267      DEF_ASM(ebp)
4268      DEF_ASM(esi)
4269      DEF_ASM(edi)
4270      DEF_ASM(mm0)
4271      DEF_ASM(mm1)
4272      DEF_ASM(mm2)
4273      DEF_ASM(mm3)
4274      DEF_ASM(mm4)
4275      DEF_ASM(mm5)
4276      DEF_ASM(mm6)
4277      DEF_ASM(mm7)
4278      DEF_ASM(xmm0)
4279      DEF_ASM(xmm1)
4280      DEF_ASM(xmm2)
4281      DEF_ASM(xmm3)
4282      DEF_ASM(xmm4)
4283      DEF_ASM(xmm5)
4284      DEF_ASM(xmm6)
4285      DEF_ASM(xmm7)
4286      DEF_ASM(cr0)
4287      DEF_ASM(cr1)
4288      DEF_ASM(cr2)
4289      DEF_ASM(cr3)
4290      DEF_ASM(cr4)
4291      DEF_ASM(cr5)
4292      DEF_ASM(cr6)
4293      DEF_ASM(cr7)
4294      DEF_ASM(tr0)
4295      DEF_ASM(tr1)
4296      DEF_ASM(tr2)
4297      DEF_ASM(tr3)
4298      DEF_ASM(tr4)
4299      DEF_ASM(tr5)
4300      DEF_ASM(tr6)
4301      DEF_ASM(tr7)
4302      DEF_ASM(db0)
4303      DEF_ASM(db1)
4304      DEF_ASM(db2)
4305      DEF_ASM(db3)
4306      DEF_ASM(db4)
4307      DEF_ASM(db5)
4308      DEF_ASM(db6)
4309      DEF_ASM(db7)
4310      DEF_ASM(dr0)
4311      DEF_ASM(dr1)
4312      DEF_ASM(dr2)
4313      DEF_ASM(dr3)
4314      DEF_ASM(dr4)
4315      DEF_ASM(dr5)
4316      DEF_ASM(dr6)
4317      DEF_ASM(dr7)
4318      DEF_ASM(es)
4319      DEF_ASM(cs)
4320      DEF_ASM(ss)
4321      DEF_ASM(ds)
4322      DEF_ASM(fs)
4323      DEF_ASM(gs)
4324      DEF_ASM(st)
4325     
4326      DEF_BWL(mov)
4327     
4328      /* generic two operands */
4329      DEF_BWL(add)
4330      DEF_BWL(or)
4331      DEF_BWL(adc)
4332      DEF_BWL(sbb)
4333      DEF_BWL(and)
4334      DEF_BWL(sub)
4335      DEF_BWL(xor)
4336      DEF_BWL(cmp)
4337     
4338      /* unary ops */
4339      DEF_BWL(inc)
4340      DEF_BWL(dec)
4341      DEF_BWL(not)
4342      DEF_BWL(neg)
4343      DEF_BWL(mul)
4344      DEF_BWL(imul)
4345      DEF_BWL(div)
4346      DEF_BWL(idiv)
4347     
4348      DEF_BWL(xchg)
4349      DEF_BWL(test)
4350     
4351      /* shifts */
4352      DEF_BWL(rol)
4353      DEF_BWL(ror)
4354      DEF_BWL(rcl)
4355      DEF_BWL(rcr)
4356      DEF_BWL(shl)
4357      DEF_BWL(shr)
4358      DEF_BWL(sar)
4359     
4360      DEF_ASM(shldw)
4361      DEF_ASM(shldl)
4362      DEF_ASM(shld)
4363      DEF_ASM(shrdw)
4364      DEF_ASM(shrdl)
4365      DEF_ASM(shrd)
4366     
4367      DEF_ASM(pushw)
4368      DEF_ASM(pushl)
4369      DEF_ASM(push)
4370      DEF_ASM(popw)
4371      DEF_ASM(popl)
4372      DEF_ASM(pop)
4373      DEF_BWL(in)
4374      DEF_BWL(out)
4375     
4376      DEF_WL(movzb)
4377     
4378      DEF_ASM(movzwl)
4379      DEF_ASM(movsbw)
4380      DEF_ASM(movsbl)
4381      DEF_ASM(movswl)
4382     
4383      DEF_WL(lea) 
4384     
4385      DEF_ASM(les) 
4386      DEF_ASM(lds) 
4387      DEF_ASM(lss) 
4388      DEF_ASM(lfs) 
4389      DEF_ASM(lgs) 
4390     
4391      DEF_ASM(call)
4392      DEF_ASM(jmp)
4393      DEF_ASM(lcall)
4394      DEF_ASM(ljmp)
4395      
4396      DEF_ASMTEST(j)
4397     
4398      DEF_ASMTEST(set)
4399      DEF_ASMTEST(cmov)
4400     
4401      DEF_WL(bsf)
4402      DEF_WL(bsr)
4403      DEF_WL(bt)
4404      DEF_WL(bts)
4405      DEF_WL(btr)
4406      DEF_WL(btc)
4407     
4408      DEF_WL(lsl)
4409     
4410      /* generic FP ops */
4411      DEF_FP(add)
4412      DEF_FP(mul)
4413     
4414      DEF_ASM(fcom)
4415      DEF_ASM(fcom_1) /* non existant op, just to have a regular table */
4416      DEF_FP1(com)
4417     
4418      DEF_FP(comp)
4419      DEF_FP(sub)
4420      DEF_FP(subr)
4421      DEF_FP(div)
4422      DEF_FP(divr)
4423     
4424      DEF_BWL(xadd)
4425      DEF_BWL(cmpxchg)
4426     
4427      /* string ops */
4428      DEF_BWL(cmps)
4429      DEF_BWL(scmp)
4430      DEF_BWL(ins)
4431      DEF_BWL(outs)
4432      DEF_BWL(lods)
4433      DEF_BWL(slod)
4434      DEF_BWL(movs)
4435      DEF_BWL(smov)
4436      DEF_BWL(scas)
4437      DEF_BWL(ssca)
4438      DEF_BWL(stos)
4439      DEF_BWL(ssto)
4440     
4441      /* generic asm ops */
4442     
4443     #define ALT(x)
4444     #define DEF_ASM_OP0(name, opcode) DEF_ASM(name)
4445     #define DEF_ASM_OP0L(name, opcode, group, instr_type)
4446     #define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
4447     #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
4448     #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
4449     // njn: inlined i386-asm.h
4450     //#include "i386-asm.h"
4451     //---------------------------------------------------------------------------
4452          DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
4453          DEF_ASM_OP0(popa, 0x61)
4454          DEF_ASM_OP0(clc, 0xf8)
4455          DEF_ASM_OP0(cld, 0xfc)
4456          DEF_ASM_OP0(cli, 0xfa)
4457          DEF_ASM_OP0(clts, 0x0f06)
4458          DEF_ASM_OP0(cmc, 0xf5)
4459          DEF_ASM_OP0(lahf, 0x9f)
4460          DEF_ASM_OP0(sahf, 0x9e)
4461          DEF_ASM_OP0(pushfl, 0x9c)
4462          DEF_ASM_OP0(popfl, 0x9d)
4463          DEF_ASM_OP0(pushf, 0x9c)
4464          DEF_ASM_OP0(popf, 0x9d)
4465          DEF_ASM_OP0(stc, 0xf9)
4466          DEF_ASM_OP0(std, 0xfd)
4467          DEF_ASM_OP0(sti, 0xfb)
4468          DEF_ASM_OP0(aaa, 0x37)
4469          DEF_ASM_OP0(aas, 0x3f)
4470          DEF_ASM_OP0(daa, 0x27)
4471          DEF_ASM_OP0(das, 0x2f)
4472          DEF_ASM_OP0(aad, 0xd50a)
4473          DEF_ASM_OP0(aam, 0xd40a)
4474          DEF_ASM_OP0(cbw, 0x6698)
4475          DEF_ASM_OP0(cwd, 0x6699)
4476          DEF_ASM_OP0(cwde, 0x98)
4477          DEF_ASM_OP0(cdq, 0x99)
4478          DEF_ASM_OP0(cbtw, 0x6698)
4479          DEF_ASM_OP0(cwtl, 0x98)
4480          DEF_ASM_OP0(cwtd, 0x6699)
4481          DEF_ASM_OP0(cltd, 0x99)
4482          DEF_ASM_OP0(int3, 0xcc)
4483          DEF_ASM_OP0(into, 0xce)
4484          DEF_ASM_OP0(iret, 0xcf)
4485          DEF_ASM_OP0(rsm, 0x0faa)
4486          DEF_ASM_OP0(hlt, 0xf4)
4487          DEF_ASM_OP0(wait, 0x9b)
4488          DEF_ASM_OP0(nop, 0x90)
4489          DEF_ASM_OP0(xlat, 0xd7)
4490     
4491          /* strings */
4492     ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
4493     ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
4494     
4495     ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
4496     ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
4497     
4498     ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
4499     ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
4500     
4501     ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
4502     ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
4503     
4504     ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
4505     ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
4506     
4507     ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
4508     ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
4509     
4510          /* bits */
4511          
4512     ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
4513     ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
4514     
4515     ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4516     ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4517     
4518     ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4519     ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4520     
4521     ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4522     ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4523     
4524     ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4525     ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4526     
4527          /* prefixes */
4528          DEF_ASM_OP0(aword, 0x67)
4529          DEF_ASM_OP0(addr16, 0x67)
4530          DEF_ASM_OP0(word, 0x66)
4531          DEF_ASM_OP0(data16, 0x66)
4532          DEF_ASM_OP0(lock, 0xf0)
4533          DEF_ASM_OP0(rep, 0xf3)
4534          DEF_ASM_OP0(repe, 0xf3)
4535          DEF_ASM_OP0(repz, 0xf3)
4536          DEF_ASM_OP0(repne, 0xf2)
4537          DEF_ASM_OP0(repnz, 0xf2)
4538                  
4539          DEF_ASM_OP0(invd, 0x0f08)
4540          DEF_ASM_OP0(wbinvd, 0x0f09)
4541          DEF_ASM_OP0(cpuid, 0x0fa2)
4542          DEF_ASM_OP0(wrmsr, 0x0f30)
4543          DEF_ASM_OP0(rdtsc, 0x0f31)
4544          DEF_ASM_OP0(rdmsr, 0x0f32)
4545          DEF_ASM_OP0(rdpmc, 0x0f33)
4546          DEF_ASM_OP0(ud2, 0x0f0b)
4547     
4548          /* NOTE: we took the same order as gas opcode definition order */
4549     ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
4550     ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
4551     ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
4552     ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
4553     ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
4554     ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
4555     
4556     ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
4557     ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
4558     
4559     ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
4560     ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
4561     ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
4562     ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
4563     ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
4564     ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
4565     
4566     ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
4567     ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
4568     ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
4569     ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
4570     ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
4571     
4572     ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
4573     ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
4574     ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
4575     ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
4576     ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
4577     
4578     ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
4579     ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
4580     ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
4581     
4582     ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
4583     ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
4584     ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
4585     ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
4586     
4587     ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
4588     ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
4589     ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
4590     ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
4591     
4592     ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
4593     ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
4594     ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
4595     ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
4596     
4597     ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
4598     
4599     ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
4600     ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
4601     ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
4602     ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
4603     ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
4604     
4605          /* arith */
4606     ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
4607     ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
4608     ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
4609     ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
4610     ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
4611     
4612     ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
4613     ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
4614     ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
4615     ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
4616     
4617     ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
4618     ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4619     ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
4620     ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4621     
4622     ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4623     ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4624     
4625     ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4626     ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4627     
4628     ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
4629     ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
4630     ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
4631     ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
4632     ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
4633     
4634     ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4635     ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
4636     ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4637     ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
4638     
4639          /* shifts */
4640     ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
4641     ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
4642     ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
4643     
4644     ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
4645     ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
4646     ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
4647     ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
4648     ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
4649     ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
4650     
4651     ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
4652     ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
4653     ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
4654     ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
4655     
4656     ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
4657     ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
4658     ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
4659     ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
4660     
4661     ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
4662     ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
4663         DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
4664         DEF_ASM_OP0(leave, 0xc9)
4665         DEF_ASM_OP0(ret, 0xc3)
4666     ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
4667         DEF_ASM_OP0(lret, 0xcb)
4668     ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
4669     
4670     ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
4671         DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
4672         DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
4673         DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
4674         DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
4675         DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
4676         DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
4677          
4678          /* float */
4679          /* specific fcomp handling */
4680     ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
4681     
4682     ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
4683     ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
4684     ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
4685     ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
4686     ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
4687     ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
4688     ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
4689     ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
4690     ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
4691     ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
4692     ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
4693     
4694          DEF_ASM_OP0(fucompp, 0xdae9)
4695          DEF_ASM_OP0(ftst, 0xd9e4)
4696          DEF_ASM_OP0(fxam, 0xd9e5)
4697          DEF_ASM_OP0(fld1, 0xd9e8)
4698          DEF_ASM_OP0(fldl2t, 0xd9e9)
4699          DEF_ASM_OP0(fldl2e, 0xd9ea)
4700          DEF_ASM_OP0(fldpi, 0xd9eb)
4701          DEF_ASM_OP0(fldlg2, 0xd9ec)
4702          DEF_ASM_OP0(fldln2, 0xd9ed)
4703          DEF_ASM_OP0(fldz, 0xd9ee)
4704     
4705          DEF_ASM_OP0(f2xm1, 0xd9f0)
4706          DEF_ASM_OP0(fyl2x, 0xd9f1)
4707          DEF_ASM_OP0(fptan, 0xd9f2)
4708          DEF_ASM_OP0(fpatan, 0xd9f3)
4709          DEF_ASM_OP0(fxtract, 0xd9f4)
4710          DEF_ASM_OP0(fprem1, 0xd9f5)
4711          DEF_ASM_OP0(fdecstp, 0xd9f6)
4712          DEF_ASM_OP0(fincstp, 0xd9f7)
4713          DEF_ASM_OP0(fprem, 0xd9f8)
4714          DEF_ASM_OP0(fyl2xp1, 0xd9f9)
4715          DEF_ASM_OP0(fsqrt, 0xd9fa)
4716          DEF_ASM_OP0(fsincos, 0xd9fb)
4717          DEF_ASM_OP0(frndint, 0xd9fc)
4718          DEF_ASM_OP0(fscale, 0xd9fd)
4719          DEF_ASM_OP0(fsin, 0xd9fe)
4720          DEF_ASM_OP0(fcos, 0xd9ff)
4721          DEF_ASM_OP0(fchs, 0xd9e0)
4722          DEF_ASM_OP0(fabs, 0xd9e1)
4723          DEF_ASM_OP0(fninit, 0xdbe3)
4724          DEF_ASM_OP0(fnclex, 0xdbe2)
4725          DEF_ASM_OP0(fnop, 0xd9d0)
4726          DEF_ASM_OP0(fwait, 0x9b)
4727     
4728         /* fp load */
4729         DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
4730         DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
4731         DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
4732     ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
4733         DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
4734         DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
4735         DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
4736         DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
4737         DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
4738         
4739         /* fp store */
4740         DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
4741         DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
4742         DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
4743         DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
4744     ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
4745         DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
4746         DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
4747         DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
4748         DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
4749         DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
4750     
4751         DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
4752         DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
4753         DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
4754         DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
4755         DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
4756     
4757         /* exchange */
4758         DEF_ASM_OP0(fxch, 0xd9c9)
4759     ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
4760     
4761         /* misc FPU */
4762         DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
4763         DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
4764     
4765         DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
4766         DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
4767         DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
4768         DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
4769         DEF_ASM_OP0(fnstsw, 0xdfe0)
4770     ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
4771     ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
4772         DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
4773     ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
4774     ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
4775         DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
4776         DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
4777         DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
4778         DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
4779         DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
4780         DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
4781         DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
4782         DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
4783         DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
4784         DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
4785         DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
4786     
4787         /* segments */
4788         DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
4789         DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
4790         DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
4791         DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
4792         DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
4793         DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
4794     ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
4795         DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
4796         DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
4797         DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
4798         DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
4799         DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
4800         DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
4801         DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
4802         DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
4803     
4804         /* 486 */
4805         DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
4806     ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
4807     ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
4808         DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
4809     
4810         DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
4811         DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
4812     
4813         /* pentium */
4814         DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
4815         
4816         /* pentium pro */
4817         ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
4818     
4819         DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
4820         DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
4821         DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
4822         DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
4823         DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
4824         DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
4825         DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
4826         DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
4827     
4828         DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
4829         DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
4830         DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
4831         DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
4832     
4833         /* mmx */
4834         DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
4835         DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
4836     ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
4837         DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4838     ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
4839         DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4840         DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4841         DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4842         DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4843         DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4844         DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4845         DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4846         DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4847         DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4848         DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4849         DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4850         DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4851         DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4852         DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4853         DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4854         DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4855         DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4856         DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4857         DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4858         DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4859         DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4860         DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4861         DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4862     ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
4863         DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4864     ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
4865         DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4866     ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
4867         DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4868     ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
4869         DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4870     ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
4871         DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4872     ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
4873         DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4874     ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
4875         DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4876     ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
4877         DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4878         DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4879         DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4880         DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4881         DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4882         DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4883         DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4884         DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4885         DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4886         DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4887         DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4888         DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4889         DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4890         DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4891     
4892     #undef ALT
4893     #undef DEF_ASM_OP0
4894     #undef DEF_ASM_OP0L
4895     #undef DEF_ASM_OP1
4896     #undef DEF_ASM_OP2
4897     #undef DEF_ASM_OP3
4898     //---------------------------------------------------------------------------
4899     
4900     #define ALT(x)
4901     #define DEF_ASM_OP0(name, opcode)
4902     #define DEF_ASM_OP0L(name, opcode, group, instr_type) DEF_ASM(name)
4903     #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) DEF_ASM(name)
4904     #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) DEF_ASM(name)
4905     #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) DEF_ASM(name)
4906     // njn: inlined i386-asm.h
4907     //#include "i386-asm.h"
4908     //---------------------------------------------------------------------------
4909          DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
4910          DEF_ASM_OP0(popa, 0x61)
4911          DEF_ASM_OP0(clc, 0xf8)
4912          DEF_ASM_OP0(cld, 0xfc)
4913          DEF_ASM_OP0(cli, 0xfa)
4914          DEF_ASM_OP0(clts, 0x0f06)
4915          DEF_ASM_OP0(cmc, 0xf5)
4916          DEF_ASM_OP0(lahf, 0x9f)
4917          DEF_ASM_OP0(sahf, 0x9e)
4918          DEF_ASM_OP0(pushfl, 0x9c)
4919          DEF_ASM_OP0(popfl, 0x9d)
4920          DEF_ASM_OP0(pushf, 0x9c)
4921          DEF_ASM_OP0(popf, 0x9d)
4922          DEF_ASM_OP0(stc, 0xf9)
4923          DEF_ASM_OP0(std, 0xfd)
4924          DEF_ASM_OP0(sti, 0xfb)
4925          DEF_ASM_OP0(aaa, 0x37)
4926          DEF_ASM_OP0(aas, 0x3f)
4927          DEF_ASM_OP0(daa, 0x27)
4928          DEF_ASM_OP0(das, 0x2f)
4929          DEF_ASM_OP0(aad, 0xd50a)
4930          DEF_ASM_OP0(aam, 0xd40a)
4931          DEF_ASM_OP0(cbw, 0x6698)
4932          DEF_ASM_OP0(cwd, 0x6699)
4933          DEF_ASM_OP0(cwde, 0x98)
4934          DEF_ASM_OP0(cdq, 0x99)
4935          DEF_ASM_OP0(cbtw, 0x6698)
4936          DEF_ASM_OP0(cwtl, 0x98)
4937          DEF_ASM_OP0(cwtd, 0x6699)
4938          DEF_ASM_OP0(cltd, 0x99)
4939          DEF_ASM_OP0(int3, 0xcc)
4940          DEF_ASM_OP0(into, 0xce)
4941          DEF_ASM_OP0(iret, 0xcf)
4942          DEF_ASM_OP0(rsm, 0x0faa)
4943          DEF_ASM_OP0(hlt, 0xf4)
4944          DEF_ASM_OP0(wait, 0x9b)
4945          DEF_ASM_OP0(nop, 0x90)
4946          DEF_ASM_OP0(xlat, 0xd7)
4947     
4948          /* strings */
4949     ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
4950     ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
4951     
4952     ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
4953     ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
4954     
4955     ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
4956     ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
4957     
4958     ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
4959     ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
4960     
4961     ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
4962     ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
4963     
4964     ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
4965     ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
4966     
4967          /* bits */
4968          
4969     ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
4970     ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
4971     
4972     ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4973     ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4974     
4975     ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4976     ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4977     
4978     ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4979     ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4980     
4981     ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4982     ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4983     
4984          /* prefixes */
4985          DEF_ASM_OP0(aword, 0x67)
4986          DEF_ASM_OP0(addr16, 0x67)
4987          DEF_ASM_OP0(word, 0x66)
4988          DEF_ASM_OP0(data16, 0x66)
4989          DEF_ASM_OP0(lock, 0xf0)
4990          DEF_ASM_OP0(rep, 0xf3)
4991          DEF_ASM_OP0(repe, 0xf3)
4992          DEF_ASM_OP0(repz, 0xf3)
4993          DEF_ASM_OP0(repne, 0xf2)
4994          DEF_ASM_OP0(repnz, 0xf2)
4995                  
4996          DEF_ASM_OP0(invd, 0x0f08)
4997          DEF_ASM_OP0(wbinvd, 0x0f09)
4998          DEF_ASM_OP0(cpuid, 0x0fa2)
4999          DEF_ASM_OP0(wrmsr, 0x0f30)
5000          DEF_ASM_OP0(rdtsc, 0x0f31)
5001          DEF_ASM_OP0(rdmsr, 0x0f32)
5002          DEF_ASM_OP0(rdpmc, 0x0f33)
5003          DEF_ASM_OP0(ud2, 0x0f0b)
5004     
5005          /* NOTE: we took the same order as gas opcode definition order */
5006     ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
5007     ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
5008     ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
5009     ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
5010     ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
5011     ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
5012     
5013     ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
5014     ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
5015     
5016     ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
5017     ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
5018     ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
5019     ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
5020     ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
5021     ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
5022     
5023     ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
5024     ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
5025     ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
5026     ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
5027     ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
5028     
5029     ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
5030     ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
5031     ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
5032     ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
5033     ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
5034     
5035     ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
5036     ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
5037     ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
5038     
5039     ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
5040     ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
5041     ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
5042     ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
5043     
5044     ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
5045     ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
5046     ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
5047     ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
5048     
5049     ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
5050     ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
5051     ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
5052     ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
5053     
5054     ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
5055     
5056     ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
5057     ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
5058     ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
5059     ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
5060     ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
5061     
5062          /* arith */
5063     ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
5064     ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
5065     ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
5066     ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
5067     ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
5068     
5069     ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
5070     ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
5071     ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
5072     ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
5073     
5074     ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
5075     ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5076     ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
5077     ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5078     
5079     ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5080     ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5081     
5082     ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5083     ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5084     
5085     ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
5086     ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
5087     ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
5088     ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
5089     ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
5090     
5091     ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5092     ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
5093     ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5094     ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
5095     
5096          /* shifts */
5097     ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
5098     ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
5099     ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
5100     
5101     ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
5102     ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
5103     ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
5104     ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
5105     ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
5106     ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
5107     
5108     ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
5109     ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
5110     ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
5111     ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
5112     
5113     ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
5114     ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
5115     ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
5116     ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
5117     
5118     ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
5119     ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
5120         DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
5121         DEF_ASM_OP0(leave, 0xc9)
5122         DEF_ASM_OP0(ret, 0xc3)
5123     ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
5124         DEF_ASM_OP0(lret, 0xcb)
5125     ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
5126     
5127     ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
5128         DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
5129         DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
5130         DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
5131         DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
5132         DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
5133         DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
5134          
5135          /* float */
5136          /* specific fcomp handling */
5137     ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
5138     
5139     ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
5140     ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
5141     ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
5142     ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
5143     ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
5144     ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
5145     ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
5146     ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
5147     ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
5148     ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
5149     ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
5150     
5151          DEF_ASM_OP0(fucompp, 0xdae9)
5152          DEF_ASM_OP0(ftst, 0xd9e4)
5153          DEF_ASM_OP0(fxam, 0xd9e5)
5154          DEF_ASM_OP0(fld1, 0xd9e8)
5155          DEF_ASM_OP0(fldl2t, 0xd9e9)
5156          DEF_ASM_OP0(fldl2e, 0xd9ea)
5157          DEF_ASM_OP0(fldpi, 0xd9eb)
5158          DEF_ASM_OP0(fldlg2, 0xd9ec)
5159          DEF_ASM_OP0(fldln2, 0xd9ed)
5160          DEF_ASM_OP0(fldz, 0xd9ee)
5161     
5162          DEF_ASM_OP0(f2xm1, 0xd9f0)
5163          DEF_ASM_OP0(fyl2x, 0xd9f1)
5164          DEF_ASM_OP0(fptan, 0xd9f2)
5165          DEF_ASM_OP0(fpatan, 0xd9f3)
5166          DEF_ASM_OP0(fxtract, 0xd9f4)
5167          DEF_ASM_OP0(fprem1, 0xd9f5)
5168          DEF_ASM_OP0(fdecstp, 0xd9f6)
5169          DEF_ASM_OP0(fincstp, 0xd9f7)
5170          DEF_ASM_OP0(fprem, 0xd9f8)
5171          DEF_ASM_OP0(fyl2xp1, 0xd9f9)
5172          DEF_ASM_OP0(fsqrt, 0xd9fa)
5173          DEF_ASM_OP0(fsincos, 0xd9fb)
5174          DEF_ASM_OP0(frndint, 0xd9fc)
5175          DEF_ASM_OP0(fscale, 0xd9fd)
5176          DEF_ASM_OP0(fsin, 0xd9fe)
5177          DEF_ASM_OP0(fcos, 0xd9ff)
5178          DEF_ASM_OP0(fchs, 0xd9e0)
5179          DEF_ASM_OP0(fabs, 0xd9e1)
5180          DEF_ASM_OP0(fninit, 0xdbe3)
5181          DEF_ASM_OP0(fnclex, 0xdbe2)
5182          DEF_ASM_OP0(fnop, 0xd9d0)
5183          DEF_ASM_OP0(fwait, 0x9b)
5184     
5185         /* fp load */
5186         DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
5187         DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
5188         DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
5189     ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
5190         DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
5191         DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
5192         DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
5193         DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
5194         DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
5195         
5196         /* fp store */
5197         DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
5198         DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
5199         DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
5200         DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
5201     ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
5202         DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
5203         DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
5204         DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
5205         DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
5206         DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
5207     
5208         DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
5209         DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
5210         DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
5211         DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
5212         DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
5213     
5214         /* exchange */
5215         DEF_ASM_OP0(fxch, 0xd9c9)
5216     ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
5217     
5218         /* misc FPU */
5219         DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
5220         DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
5221     
5222         DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
5223         DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
5224         DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
5225         DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
5226         DEF_ASM_OP0(fnstsw, 0xdfe0)
5227     ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
5228     ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
5229         DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
5230     ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
5231     ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
5232         DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
5233         DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
5234         DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
5235         DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
5236         DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
5237         DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
5238         DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
5239         DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
5240         DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
5241         DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
5242         DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
5243     
5244         /* segments */
5245         DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
5246         DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
5247         DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
5248         DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
5249         DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
5250         DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
5251     ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
5252         DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
5253         DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
5254         DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
5255         DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
5256         DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
5257         DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
5258         DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
5259         DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
5260     
5261         /* 486 */
5262         DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
5263     ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
5264     ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
5265         DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
5266     
5267         DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
5268         DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
5269     
5270         /* pentium */
5271         DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
5272         
5273         /* pentium pro */
5274         ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
5275     
5276         DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
5277         DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
5278         DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
5279         DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
5280         DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
5281         DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
5282         DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
5283         DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
5284     
5285         DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
5286         DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
5287         DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
5288         DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
5289     
5290         /* mmx */
5291         DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
5292         DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
5293     ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
5294         DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5295     ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
5296         DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5297         DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5298         DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5299         DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5300         DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5301         DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5302         DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5303         DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5304         DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5305         DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5306         DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5307         DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5308         DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5309         DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5310         DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5311         DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5312         DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5313         DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5314         DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5315         DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5316         DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5317         DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5318         DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5319     ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
5320         DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5321     ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
5322         DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5323     ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
5324         DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5325     ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
5326         DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5327     ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
5328         DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5329     ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
5330         DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5331     ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
5332         DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5333     ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
5334         DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5335         DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5336         DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5337         DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5338         DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5339         DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5340         DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5341         DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5342         DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5343         DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5344         DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5345         DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5346         DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5347         DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5348     
5349     #undef ALT
5350     #undef DEF_ASM_OP0
5351     #undef DEF_ASM_OP0L
5352     #undef DEF_ASM_OP1
5353     #undef DEF_ASM_OP2
5354     #undef DEF_ASM_OP3
5355     //---------------------------------------------------------------------------
5356     
5357     #endif
5358     //---------------------------------------------------------------------------
5359     #undef DEF
5360     ;
5361     
5362     #define TOK_UIDENT TOK_DEFINE
5363     
5364     #ifdef WIN32
5365     int __stdcall GetModuleFileNameA(void *, char *, int);
5366     void *__stdcall GetProcAddress(void *, const char *);
5367     void *__stdcall GetModuleHandleA(const char *);
5368     void *__stdcall LoadLibraryA(const char *);
5369     int __stdcall FreeConsole(void);
5370     
5371     #define snprintf _snprintf
5372     #define vsnprintf _vsnprintf
5373     #ifndef __GNUC__
5374       #define strtold (long double)strtod
5375       #define strtof (float)strtod
5376       #define strtoll (long long)strtol
5377     #endif
5378     #elif defined(TCC_UCLIBC) || defined(__FreeBSD__)
5379     /* currently incorrect */
5380     long double strtold(const char *nptr, char **endptr)
5381     {
5382         return (long double)strtod(nptr, endptr);
5383     }
5384     float strtof(const char *nptr, char **endptr)
5385     {
5386         return (float)strtod(nptr, endptr);
5387     }
5388     #else
5389     /* XXX: need to define this to use them in non ISOC99 context */
5390     extern float strtof (const char *__nptr, char **__endptr);
5391     extern long double strtold (const char *__nptr, char **__endptr);
5392     #endif
5393     
5394     static char *pstrcpy(char *buf, int buf_size, const char *s);
5395     static char *pstrcat(char *buf, int buf_size, const char *s);
5396     static const char *tcc_basename(const char *name);
5397     
5398     static void next(void);
5399     static void next_nomacro(void);
5400     static void parse_expr_type(CType *type);
5401     static void expr_type(CType *type);
5402     static void unary_type(CType *type);
5403     static void block(int *bsym, int *csym, int *case_sym, int *def_sym, 
5404                       int case_reg, int is_expr);
5405     static int expr_const(void);
5406     static void expr_eq(void);
5407     static void gexpr(void);
5408     static void gen_inline_functions(void);
5409     static void decl(int l);
5410     static void decl_initializer(CType *type, Section *sec, unsigned long c, 
5411                                  int first, int size_only);
5412     static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, 
5413                                        int has_init, int v, int scope);
5414     int gv(int rc);
5415     void gv2(int rc1, int rc2);
5416     void move_reg(int r, int s);
5417     void save_regs(int n);
5418     void save_reg(int r);
5419     void vpop(void);
5420     void vswap(void);
5421     void vdup(void);
5422     int get_reg(int rc);
5423     int get_reg_ex(int rc,int rc2);
5424     
5425     struct macro_level {
5426         struct macro_level *prev;
5427         int *p;
5428     };
5429     
5430     static void macro_subst(TokenString *tok_str, Sym **nested_list, 
5431                             const int *macro_str, struct macro_level **can_read_stream);
5432     void gen_op(int op);
5433     void force_charshort_cast(int t);
5434     static void gen_cast(CType *type);
5435     void vstore(void);
5436     static Sym *sym_find(int v);
5437     static Sym *sym_push(int v, CType *type, int r, int c);
5438     
5439     /* type handling */
5440     static int type_size(CType *type, int *a);
5441     static inline CType *pointed_type(CType *type);
5442     static int pointed_size(CType *type);
5443     static int lvalue_type(int t);
5444     static int parse_btype(CType *type, AttributeDef *ad);
5445     static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
5446     static int is_compatible_types(CType *type1, CType *type2);
5447     
5448     int ieee_finite(double d);
5449     void error(const char *fmt, ...);
5450     void vpushi(int v);
5451     void vrott(int n);
5452     void vnrott(int n);
5453     void lexpand_nr(void);
5454     static void vpush_global_sym(CType *type, int v);
5455     void vset(CType *type, int r, int v);
5456     void type_to_str(char *buf, int buf_size, 
5457                      CType *type, const char *varstr);
5458     char *get_tok_str(int v, CValue *cv);
5459     static Sym *get_sym_ref(CType *type, Section *sec, 
5460                             unsigned long offset, unsigned long size);
5461     static Sym *external_global_sym(int v, CType *type, int r);
5462     
5463     /* section generation */
5464     static void section_realloc(Section *sec, unsigned long new_size);
5465     static void *section_ptr_add(Section *sec, unsigned long size);
5466     static void put_extern_sym(Sym *sym, Section *section, 
5467                                unsigned long value, unsigned long size);
5468     static void greloc(Section *s, Sym *sym, unsigned long addr, int type);
5469     static int put_elf_str(Section *s, const char *sym);
5470     static int put_elf_sym(Section *s, 
5471                            unsigned long value, unsigned long size,
5472                            int info, int other, int shndx, const char *name);
5473     static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
5474                            int info, int other, int sh_num, const char *name);
5475     static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
5476                               int type, int symbol);
5477     static void put_stabs(const char *str, int type, int other, int desc, 
5478                           unsigned long value);
5479     static void put_stabs_r(const char *str, int type, int other, int desc, 
5480                             unsigned long value, Section *sec, int sym_index);
5481     static void put_stabn(int type, int other, int desc, int value);
5482     static void put_stabd(int type, int other, int desc);
5483     static int tcc_add_dll(TCCState *s, const char *filename, int flags);
5484     
5485     #define AFF_PRINT_ERROR     0x0001 /* print error if file not found */
5486     #define AFF_REFERENCED_DLL  0x0002 /* load a referenced dll from another dll */
5487     static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
5488     
5489     /* tcccoff.c */
5490     int tcc_output_coff(TCCState *s1, FILE *f);
5491     
5492     /* tccpe.c */
5493     void *resolve_sym(TCCState *s1, const char *sym, int type);
5494     int pe_load_def_file(struct TCCState *s1, FILE *fp);
5495     void pe_setup_paths(struct TCCState *s1, int *p_output_type, const char **p_outfile, char *first_file);
5496     unsigned long pe_add_runtime(struct TCCState *s1);
5497     int tcc_output_pe(struct TCCState *s1, const char *filename);
5498     
5499     /* tccasm.c */
5500     
5501     #ifdef CONFIG_TCC_ASM
5502     
5503     typedef struct ExprValue {
5504         uint32_t v;
5505         Sym *sym;
5506     } ExprValue;
5507     
5508     #define MAX_ASM_OPERANDS 30
5509     
5510     typedef struct ASMOperand {
5511         int id; /* GCC 3 optionnal identifier (0 if number only supported */
5512         char *constraint;
5513         char asm_str[16]; /* computed asm string for operand */
5514         SValue *vt; /* C value of the expression */
5515         int ref_index; /* if >= 0, gives reference to a output constraint */
5516         int input_index; /* if >= 0, gives reference to an input constraint */
5517         int priority; /* priority, used to assign registers */
5518         int reg; /* if >= 0, register number used for this operand */
5519         int is_llong; /* true if double register value */
5520         int is_memory; /* true if memory operand */
5521         int is_rw;     /* for '+' modifier */
5522     } ASMOperand;
5523     
5524     static void asm_expr(TCCState *s1, ExprValue *pe);
5525     static int asm_int_expr(TCCState *s1);
5526     static int find_constraint(ASMOperand *operands, int nb_operands, 
5527                                const char *name, const char **pp);
5528     
5529     static int tcc_assemble(TCCState *s1, int do_preprocess);
5530     
5531     #endif
5532     
5533     static void asm_instr(void);
5534     static void asm_global_instr(void);
5535     
5536     /* true if float/double/long double type */
5537     static inline int is_float(int t)
5538     {
5539         int bt;
5540         bt = t & VT_BTYPE;
5541         return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
5542     }
5543     
5544     #ifdef TCC_TARGET_I386
5545     // njn: inlined i386-gen.c
5546     //#include "i386-gen.c"
5547     //---------------------------------------------------------------------------
5548     /*
5549      *  X86 code generator for TCC
5550      * 
5551      *  Copyright (c) 2001-2004 Fabrice Bellard
5552      *
5553      * This library is free software; you can redistribute it and/or
5554      * modify it under the terms of the GNU Lesser General Public
5555      * License as published by the Free Software Foundation; either
5556      * version 2 of the License, or (at your option) any later version.
5557      *
5558      * This library is distributed in the hope that it will be useful,
5559      * but WITHOUT ANY WARRANTY; without even the implied warranty of
5560      * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
5561      * Lesser General Public License for more details.
5562      *
5563      * You should have received a copy of the GNU Lesser General Public
5564      * License along with this library; if not, write to the Free Software
5565      * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
5566      */
5567     
5568     /* number of available registers */
5569     #define NB_REGS             4
5570     
5571     /* a register can belong to several classes. The classes must be
5572        sorted from more general to more precise (see gv2() code which does
5573        assumptions on it). */
5574     #define RC_INT     0x0001 /* generic integer register */
5575     #define RC_FLOAT   0x0002 /* generic float register */
5576     #define RC_EAX     0x0004
5577     #define RC_ST0     0x0008 
5578     #define RC_ECX     0x0010
5579     #define RC_EDX     0x0020
5580     #define RC_IRET    RC_EAX /* function return: integer register */
5581     #define RC_LRET    RC_EDX /* function return: second integer register */
5582     #define RC_FRET    RC_ST0 /* function return: float register */
5583     
5584     /* pretty names for the registers */
5585     enum {
5586         TREG_EAX = 0,
5587         TREG_ECX,
5588         TREG_EDX,
5589         TREG_ST0,
5590     };
5591     
5592     int reg_classes[NB_REGS] = {
5593         /* eax */ RC_INT | RC_EAX,
5594         /* ecx */ RC_INT | RC_ECX,
5595         /* edx */ RC_INT | RC_EDX,
5596         /* st0 */ RC_FLOAT | RC_ST0,
5597     };
5598     
5599     /* return registers for function */
5600     #define REG_IRET TREG_EAX /* single word int return register */
5601     #define REG_LRET TREG_EDX /* second word return register (for long long) */
5602     #define REG_FRET TREG_ST0 /* float return register */
5603     
5604     /* defined if function parameters must be evaluated in reverse order */
5605     #define INVERT_FUNC_PARAMS
5606     
5607     /* defined if structures are passed as pointers. Otherwise structures
5608        are directly pushed on stack. */
5609     //#define FUNC_STRUCT_PARAM_AS_PTR
5610     
5611     /* pointer size, in bytes */
5612     #define PTR_SIZE 4
5613     
5614     /* long double size and alignment, in bytes */
5615     #define LDOUBLE_SIZE  12
5616     #define LDOUBLE_ALIGN 4
5617     /* maximum alignment (for aligned attribute support) */
5618     #define MAX_ALIGN     8
5619     
5620     /******************************************************/
5621     /* ELF defines */
5622     
5623     #define EM_TCC_TARGET EM_386
5624     
5625     /* relocation type for 32 bit data relocation */
5626     #define R_DATA_32   R_386_32
5627     #define R_JMP_SLOT  R_386_JMP_SLOT
5628     #define R_COPY      R_386_COPY
5629     
5630     #define ELF_START_ADDR 0x08048000
5631     #define ELF_PAGE_SIZE  0x1000
5632     
5633     /******************************************************/
5634     
5635     static unsigned long func_sub_sp_offset;
5636     static unsigned long func_bound_offset;
5637     static int func_ret_sub;
5638     
5639     /* XXX: make it faster ? */
5640     void g(int c)
5641     {
5642         int ind1;
5643         ind1 = ind + 1;
5644         if (ind1 > cur_text_section->data_allocated)
5645             section_realloc(cur_text_section, ind1);
5646         cur_text_section->data[ind] = c;
5647         ind = ind1;
5648     }
5649     
5650     void o(unsigned int c)
5651     {
5652         while (c) {
5653             g(c);
5654             c = c >> 8;
5655         }
5656     }
5657     
5658     void gen_le32(int c)
5659     {
5660         g(c);
5661         g(c >> 8);
5662         g(c >> 16);
5663         g(c >> 24);
5664     }
5665     
5666     /* output a symbol and patch all calls to it */
5667     void gsym_addr(int t, int a)
5668     {
5669         int n, *ptr;
5670         while (t) {
5671             ptr = (int *)(cur_text_section->data + t);
5672             n = *ptr; /* next value */
5673             *ptr = a - t - 4;
5674             t = n;
5675         }
5676     }
5677     
5678     void gsym(int t)
5679     {
5680         gsym_addr(t, ind);
5681     }
5682     
5683     /* psym is used to put an instruction with a data field which is a
5684        reference to a symbol. It is in fact the same as oad ! */
5685     #define psym oad
5686     
5687     /* instruction + 4 bytes data. Return the address of the data */
5688     static int oad(int c, int s)
5689     {
5690         int ind1;
5691     
5692         o(c);
5693         ind1 = ind + 4;
5694         if (ind1 > cur_text_section->data_allocated)
5695             section_realloc(cur_text_section, ind1);
5696         *(int *)(cur_text_section->data + ind) = s;
5697         s = ind;
5698         ind = ind1;
5699         return s;
5700     }
5701     
5702     /* output constant with relocation if 'r & VT_SYM' is true */
5703     static void gen_addr32(int r, Sym *sym, int c)
5704     {
5705         if (r & VT_SYM)
5706             greloc(cur_text_section, sym, ind, R_386_32);
5707         gen_le32(c);
5708     }
5709     
5710     /* generate a modrm reference. 'op_reg' contains the addtionnal 3
5711        opcode bits */
5712     static void gen_modrm(int op_reg, int r, Sym *sym, int c)
5713     {
5714         op_reg = op_reg << 3;
5715         if ((r & VT_VALMASK) == VT_CONST) {
5716             /* constant memory reference */
5717             o(0x05 | op_reg);
5718             gen_addr32(r, sym, c);
5719         } else if ((r & VT_VALMASK) == VT_LOCAL) {
5720             /* currently, we use only ebp as base */
5721             if (c == (char)c) {
5722                 /* short reference */
5723                 o(0x45 | op_reg);
5724                 g(c);
5725             } else {
5726                 oad(0x85 | op_reg, c);
5727             }
5728         } else {
5729             g(0x00 | op_reg | (r & VT_VALMASK));
5730         }
5731     }
5732     
5733     
5734     /* load 'r' from value 'sv' */
5735     void load(int r, SValue *sv)
5736     {
5737         int v, t, ft, fc, fr;
5738         SValue v1;
5739     
5740         fr = sv->r;
5741         ft = sv->type.t;
5742         fc = sv->c.ul;
5743     
5744         v = fr & VT_VALMASK;
5745         if (fr & VT_LVAL) {
5746             if (v == VT_LLOCAL) {
5747                 v1.type.t = VT_INT;
5748                 v1.r = VT_LOCAL | VT_LVAL;
5749                 v1.c.ul = fc;
5750                 load(r, &v1);
5751                 fr = r;
5752             }
5753             if ((ft & VT_BTYPE) == VT_FLOAT) {
5754                 o(0xd9); /* flds */
5755                 r = 0;
5756             } else if ((ft & VT_BTYPE) == VT_DOUBLE) {
5757                 o(0xdd); /* fldl */
5758                 r = 0;
5759             } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
5760                 o(0xdb); /* fldt */
5761                 r = 5;
5762             } else if ((ft & VT_TYPE) == VT_BYTE) {
5763                 o(0xbe0f);   /* movsbl */
5764             } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
5765                 o(0xb60f);   /* movzbl */
5766             } else if ((ft & VT_TYPE) == VT_SHORT) {
5767                 o(0xbf0f);   /* movswl */
5768             } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) {
5769                 o(0xb70f);   /* movzwl */
5770             } else {
5771                 o(0x8b);     /* movl */
5772             }
5773             gen_modrm(r, fr, sv->sym, fc);
5774         } else {
5775             if (v == VT_CONST) {
5776                 o(0xb8 + r); /* mov $xx, r */
5777                 gen_addr32(fr, sv->sym, fc);
5778             } else if (v == VT_LOCAL) {
5779                 o(0x8d); /* lea xxx(%ebp), r */
5780                 gen_modrm(r, VT_LOCAL, sv->sym, fc);
5781             } else if (v == VT_CMP) {
5782                 oad(0xb8 + r, 0); /* mov $0, r */
5783                 o(0x0f); /* setxx %br */
5784                 o(fc);
5785                 o(0xc0 + r);
5786             } else if (v == VT_JMP || v == VT_JMPI) {
5787                 t = v & 1;
5788                 oad(0xb8 + r, t); /* mov $1, r */
5789                 o(0x05eb); /* jmp after */
5790                 gsym(fc);
5791                 oad(0xb8 + r, t ^ 1); /* mov $0, r */
5792             } else if (v != r) {
5793                 o(0x89);
5794                 o(0xc0 + r + v * 8); /* mov v, r */
5795             }
5796         }
5797     }
5798     
5799     /* store register 'r' in lvalue 'v' */
5800     void store(int r, SValue *v)
5801     {
5802         int fr, bt, ft, fc;
5803     
5804         ft = v->type.t;
5805         fc = v->c.ul;
5806         fr = v->r & VT_VALMASK;
5807         bt = ft & VT_BTYPE;
5808         /* XXX: incorrect if float reg to reg */
5809         if (bt == VT_FLOAT) {
5810             o(0xd9); /* fsts */
5811             r = 2;
5812         } else if (bt == VT_DOUBLE) {
5813             o(0xdd); /* fstpl */
5814             r = 2;
5815         } else if (bt == VT_LDOUBLE) {
5816             o(0xc0d9); /* fld %st(0) */
5817             o(0xdb); /* fstpt */
5818             r = 7;
5819         } else {
5820             if (bt == VT_SHORT)
5821                 o(0x66);
5822             if (bt == VT_BYTE || bt == VT_BOOL)
5823                 o(0x88);
5824             else
5825                 o(0x89);
5826         }
5827         if (fr == VT_CONST ||
5828             fr == VT_LOCAL ||
5829             (v->r & VT_LVAL)) {
5830             gen_modrm(r, v->r, v->sym, fc);
5831         } else if (fr != r) {
5832             o(0xc0 + fr + r * 8); /* mov r, fr */
5833         }
5834     }
5835     
5836     static void gadd_sp(int val)
5837     {
5838         if (val == (char)val) {
5839             o(0xc483);
5840             g(val);
5841         } else {
5842             oad(0xc481, val); /* add $xxx, %esp */
5843         }
5844     }
5845     
5846     /* 'is_jmp' is '1' if it is a jump */
5847     static void gcall_or_jmp(int is_jmp)
5848     {
5849         int r;
5850         if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
5851             /* constant case */
5852             if (vtop->r & VT_SYM) {
5853                 /* relocation case */
5854                 greloc(cur_text_section, vtop->sym, 
5855                        ind + 1, R_386_PC32);
5856             } else {
5857                 /* put an empty PC32 relocation */
5858                 put_elf_reloc(symtab_section, cur_text_section, 
5859                               ind + 1, R_386_PC32, 0);
5860             }
5861             oad(0xe8 + is_jmp, vtop->c.ul - 4); /* call/jmp im */
5862         } else {
5863             /* otherwise, indirect call */
5864             r = gv(RC_INT);
5865             o(0xff); /* call/jmp *r */
5866             o(0xd0 + r + (is_jmp << 4));
5867         }
5868     }
5869     
5870     static uint8_t fastcall_regs[3] = { TREG_EAX, TREG_EDX, TREG_ECX };
5871     
5872     /* Generate function call. The function address is pushed first, then
5873        all the parameters in call order. This functions pops all the
5874        parameters and the function address. */
5875     void gfunc_call(int nb_args)
5876     {
5877         int size, align, r, args_size, i, func_call;
5878         Sym *func_sym;
5879         
5880         args_size = 0;
5881         for(i = 0;i < nb_args; i++) {
5882             if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
5883                 size = type_size(&vtop->type, &align);
5884                 /* align to stack align size */
5885                 size = (size + 3) & ~3;
5886                 /* allocate the necessary size on stack */
5887                 oad(0xec81, size); /* sub $xxx, %esp */
5888                 /* generate structure store */
5889                 r = get_reg(RC_INT);
5890                 o(0x89); /* mov %esp, r */
5891                 o(0xe0 + r);
5892                 vset(&vtop->type, r | VT_LVAL, 0);
5893                 vswap();
5894                 vstore();
5895                 args_size += size;
5896             } else if (is_float(vtop->type.t)) {
5897                 gv(RC_FLOAT); /* only one float register */
5898                 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT)
5899                     size = 4;
5900                 else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
5901                     size = 8;
5902                 else
5903                     size = 12;
5904                 oad(0xec81, size); /* sub $xxx, %esp */
5905                 if (size == 12)
5906                     o(0x7cdb);
5907                 else
5908                     o(0x5cd9 + size - 4); /* fstp[s|l] 0(%esp) */
5909                 g(0x24);
5910                 g(0x00);
5911                 args_size += size;
5912             } else {
5913                 /* simple type (currently always same size) */
5914                 /* XXX: implicit cast ? */
5915                 r = gv(RC_INT);
5916                 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
5917                     size = 8;
5918                     o(0x50 + vtop->r2); /* push r */
5919                 } else {
5920                     size = 4;
5921                 }
5922                 o(0x50 + r); /* push r */
5923                 args_size += size;
5924             }
5925             vtop--;
5926         }
5927         save_regs(0); /* save used temporary registers */
5928         func_sym = vtop->type.ref;
5929         func_call = func_sym->r;
5930         /* fast call case */
5931         if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
5932             int fastcall_nb_regs;
5933             fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
5934             for(i = 0;i < fastcall_nb_regs; i++) {
5935                 if (args_size <= 0)
5936                     break;
5937                 o(0x58 + fastcall_regs[i]); /* pop r */
5938                 /* XXX: incorrect for struct/floats */
5939                 args_size -= 4;
5940             }
5941         }
5942         gcall_or_jmp(0);
5943         if (args_size && func_sym->r != FUNC_STDCALL)
5944             gadd_sp(args_size);
5945         vtop--;
5946     }
5947     
5948     #ifdef TCC_TARGET_PE
5949     #define FUNC_PROLOG_SIZE 10
5950     #else
5951     #define FUNC_PROLOG_SIZE 9
5952     #endif
5953     
5954     /* generate function prolog of type 't' */
5955     void gfunc_prolog(CType *func_type)
5956     {
5957         int addr, align, size, func_call, fastcall_nb_regs;
5958         int param_index, param_addr;
5959         Sym *sym;
5960         CType *type;
5961     
5962         sym = func_type->ref;
5963         func_call = sym->r;
5964         addr = 8;
5965         loc = 0;
5966         if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
5967             fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
5968         } else {
5969             fastcall_nb_regs = 0;
5970         }
5971         param_index = 0;
5972     
5973         ind += FUNC_PROLOG_SIZE;
5974         func_sub_sp_offset = ind;
5975         /* if the function returns a structure, then add an
5976            implicit pointer parameter */
5977         func_vt = sym->type;
5978         if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
5979             /* XXX: fastcall case ? */
5980             func_vc = addr;
5981             addr += 4;
5982             param_index++;
5983         }
5984         /* define parameters */
5985         while ((sym = sym->next) != NULL) {
5986             type = &sym->type;
5987             size = type_size(type, &align);
5988             size = (size + 3) & ~3;
5989     #ifdef FUNC_STRUCT_PARAM_AS_PTR
5990             /* structs are passed as pointer */
5991             if ((type->t & VT_BTYPE) == VT_STRUCT) {
5992                 size = 4;
5993             }
5994     #endif
5995             if (param_index < fastcall_nb_regs) {
5996                 /* save FASTCALL register */
5997                 loc -= 4;
5998                 o(0x89);     /* movl */
5999                 gen_modrm(fastcall_regs[param_index], VT_LOCAL, NULL, loc);
6000                 param_addr = loc;
6001             } else {
6002                 param_addr = addr;
6003                 addr += size;
6004             }
6005             sym_push(sym->v & ~SYM_FIELD, type,
6006                      VT_LOCAL | VT_LVAL, param_addr);
6007             param_index++;
6008         }
6009         func_ret_sub = 0;
6010         /* pascal type call ? */
6011         if (func_call == FUNC_STDCALL)
6012             func_ret_sub = addr - 8;
6013     
6014         /* leave some room for bound checking code */
6015         if (do_bounds_check) {
6016             oad(0xb8, 0); /* lbound section pointer */
6017             oad(0xb8, 0); /* call to function */
6018             func_bound_offset = lbounds_section->data_offset;
6019         }
6020     }
6021     
6022     /* generate function epilog */
6023     void gfunc_epilog(void)
6024     {
6025         int v, saved_ind;
6026     
6027     #ifdef CONFIG_TCC_BCHECK
6028         if (do_bounds_check && func_bound_offset != lbounds_section->data_offset) {
6029             int saved_ind;
6030             int *bounds_ptr;
6031             Sym *sym, *sym_data;
6032             /* add end of table info */
6033             bounds_ptr = section_ptr_add(lbounds_section, sizeof(int));
6034             *bounds_ptr = 0;
6035             /* generate bound local allocation */
6036             saved_ind = ind;
6037             ind = func_sub_sp_offset;
6038             sym_data = get_sym_ref(&char_pointer_type, lbounds_section, 
6039                                    func_bound_offset, lbounds_section->data_offset);
6040             greloc(cur_text_section, sym_data,
6041                    ind + 1, R_386_32);
6042             oad(0xb8, 0); /* mov %eax, xxx */
6043             sym = external_global_sym(TOK___bound_local_new, &func_old_type, 0);
6044             greloc(cur_text_section, sym, 
6045                    ind + 1, R_386_PC32);
6046             oad(0xe8, -4);
6047             ind = saved_ind;
6048             /* generate bound check local freeing */
6049             o(0x5250); /* save returned value, if any */
6050             greloc(cur_text_section, sym_data,
6051                    ind + 1, R_386_32);
6052             oad(0xb8, 0); /* mov %eax, xxx */
6053             sym = external_global_sym(TOK___bound_local_delete, &func_old_type, 0);
6054             greloc(cur_text_section, sym, 
6055                    ind + 1, R_386_PC32);
6056             oad(0xe8, -4);
6057             o(0x585a); /* restore returned value, if any */
6058         }
6059     #endif
6060         o(0xc9); /* leave */
6061         if (func_ret_sub == 0) {
6062             o(0xc3); /* ret */
6063         } else {
6064             o(0xc2); /* ret n */
6065             g(func_ret_sub);
6066             g(func_ret_sub >> 8);
6067         }
6068         /* align local size to word & save local variables */
6069         
6070         v = (-loc + 3) & -4; 
6071         saved_ind = ind;
6072         ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
6073     #ifdef TCC_TARGET_PE
6074         if (v >= 4096) {
6075             Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0);
6076             oad(0xb8, v); /* mov stacksize, %eax */
6077             oad(0xe8, -4); /* call __chkstk, (does the stackframe too) */
6078             greloc(cur_text_section, sym, ind-4, R_386_PC32);
6079         } else
6080     #endif
6081         {
6082             o(0xe58955);  /* push %ebp, mov %esp, %ebp */
6083             o(0xec81);  /* sub esp, stacksize */
6084             gen_le32(v);
6085     #if FUNC_PROLOG_SIZE == 10
6086             o(0x90);  /* adjust to FUNC_PROLOG_SIZE */
6087     #endif
6088         }
6089         ind = saved_ind;
6090     }
6091     
6092     /* generate a jump to a label */
6093     long gjmp(int t)
6094     {
6095         return psym(0xe9, t);
6096     }
6097     
6098     /* generate a jump to a fixed address */
6099     void gjmp_addr(int a)
6100     {
6101         int r;
6102         r = a - ind - 2;
6103         if (r == (char)r) {
6104             g(0xeb);
6105             g(r);
6106         } else {
6107             oad(0xe9, a - ind - 5);
6108         }
6109     }
6110     
6111     /* generate a test. set 'inv' to invert test. Stack entry is popped */
6112     int gtst(int inv, int t)
6113     {
6114         int v, *p;
6115     
6116         v = vtop->r & VT_VALMASK;
6117         if (v == VT_CMP) {
6118             /* fast case : can jump directly since flags are set */
6119             g(0x0f);
6120             t = psym((vtop->c.i - 16) ^ inv, t);
6121         } else if (v == VT_JMP || v == VT_JMPI) {
6122             /* && or || optimization */
6123             if ((v & 1) == inv) {
6124                 /* insert vtop->c jump list in t */
6125                 p = &vtop->c.i;
6126                 while (*p != 0)
6127                     p = (int *)(cur_text_section->data + *p);
6128                 *p = t;
6129                 t = vtop->c.i;
6130             } else {
6131                 t = gjmp(t);
6132                 gsym(vtop->c.i);
6133             }
6134         } else {
6135             if (is_float(vtop->type.t)) {
6136                 vpushi(0);
6137                 gen_op(TOK_NE);
6138             }
6139             if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
6140                 /* constant jmp optimization */
6141                 if ((vtop->c.i != 0) != inv) 
6142                     t = gjmp(t);
6143             } else {
6144                 v = gv(RC_INT);
6145                 o(0x85);
6146                 o(0xc0 + v * 9);
6147                 g(0x0f);
6148                 t = psym(0x85 ^ inv, t);
6149             }
6150         }
6151         vtop--;
6152         return t;
6153     }
6154     
6155     /* generate an integer binary operation */
6156     void gen_opi(int op)
6157     {
6158         int r, fr, opc, c;
6159     
6160         switch(op) {
6161         case '+':
6162         case TOK_ADDC1: /* add with carry generation */
6163             opc = 0;
6164         gen_op8:
6165             if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
6166                 /* constant case */
6167                 vswap();
6168                 r = gv(RC_INT);
6169                 vswap();
6170                 c = vtop->c.i;
6171                 if (c == (char)c) {
6172                     /* XXX: generate inc and dec for smaller code ? */
6173                     o(0x83);
6174                     o(0xc0 | (opc << 3) | r);
6175                     g(c);
6176                 } else {
6177                     o(0x81);
6178                     oad(0xc0 | (opc << 3) | r, c);
6179                 }
6180             } else {
6181                 gv2(RC_INT, RC_INT);
6182                 r = vtop[-1].r;
6183                 fr = vtop[0].r;
6184                 o((opc << 3) | 0x01);
6185                 o(0xc0 + r + fr * 8); 
6186             }
6187             vtop--;
6188             if (op >= TOK_ULT && op <= TOK_GT) {
6189                 vtop->r = VT_CMP;
6190                 vtop->c.i = op;
6191             }
6192             break;
6193         case '-':
6194         case TOK_SUBC1: /* sub with carry generation */
6195             opc = 5;
6196             goto gen_op8;
6197         case TOK_ADDC2: /* add with carry use */
6198             opc = 2;
6199             goto gen_op8;
6200         case TOK_SUBC2: /* sub with carry use */
6201             opc = 3;
6202             goto gen_op8;
6203         case '&':
6204             opc = 4;
6205             goto gen_op8;
6206         case '^':
6207             opc = 6;
6208             goto gen_op8;
6209         case '|':
6210             opc = 1;
6211             goto gen_op8;
6212         case '*':
6213             gv2(RC_INT, RC_INT);
6214             r = vtop[-1].r;
6215             fr = vtop[0].r;
6216             vtop--;
6217             o(0xaf0f); /* imul fr, r */
6218             o(0xc0 + fr + r * 8);
6219             break;
6220         case TOK_SHL:
6221             opc = 4;
6222             goto gen_shift;
6223         case TOK_SHR:
6224             opc = 5;
6225             goto gen_shift;
6226         case TOK_SAR:
6227             opc = 7;
6228         gen_shift:
6229             opc = 0xc0 | (opc << 3);
6230             if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
6231                 /* constant case */
6232                 vswap();
6233                 r = gv(RC_INT);
6234                 vswap();
6235                 c = vtop->c.i & 0x1f;
6236                 o(0xc1); /* shl/shr/sar $xxx, r */
6237                 o(opc | r);
6238                 g(c);
6239             } else {
6240                 /* we generate the shift in ecx */
6241                 gv2(RC_INT, RC_ECX);
6242                 r = vtop[-1].r;
6243                 o(0xd3); /* shl/shr/sar %cl, r */
6244                 o(opc | r);
6245             }
6246             vtop--;
6247             break;
6248         case '/':
6249         case TOK_UDIV:
6250         case TOK_PDIV:
6251         case '%':
6252         case TOK_UMOD:
6253         case TOK_UMULL:
6254             /* first operand must be in eax */
6255             /* XXX: need better constraint for second operand */
6256             gv2(RC_EAX, RC_ECX);
6257             r = vtop[-1].r;
6258             fr = vtop[0].r;
6259             vtop--;
6260             save_reg(TREG_EDX);
6261             if (op == TOK_UMULL) {
6262                 o(0xf7); /* mul fr */
6263                 o(0xe0 + fr);
6264                 vtop->r2 = TREG_EDX;
6265                 r = TREG_EAX;
6266             } else {
6267                 if (op == TOK_UDIV || op == TOK_UMOD) {
6268                     o(0xf7d231); /* xor %edx, %edx, div fr, %eax */
6269                     o(0xf0 + fr);
6270                 } else {
6271                     o(0xf799); /* cltd, idiv fr, %eax */
6272                     o(0xf8 + fr);
6273                 }
6274                 if (op == '%' || op == TOK_UMOD)
6275                     r = TREG_EDX;
6276                 else
6277                     r = TREG_EAX;
6278             }
6279             vtop->r = r;
6280             break;
6281         default:
6282             opc = 7;
6283             goto gen_op8;
6284         }
6285     }
6286     
6287     /* generate a floating point operation 'v = t1 op t2' instruction. The
6288        two operands are guaranted to have the same floating point type */
6289     /* XXX: need to use ST1 too */
6290     void gen_opf(int op)
6291     {
6292         int a, ft, fc, swapped, r;
6293     
6294         /* convert constants to memory references */
6295         if ((vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
6296             vswap();
6297             gv(RC_FLOAT);
6298             vswap();
6299         }
6300         if ((vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
6301             gv(RC_FLOAT);
6302     
6303         /* must put at least one value in the floating point register */
6304         if ((vtop[-1].r & VT_LVAL) &&
6305             (vtop[0].r & VT_LVAL)) {
6306             vswap();
6307             gv(RC_FLOAT);
6308             vswap();
6309         }
6310         swapped = 0;
6311         /* swap the stack if needed so that t1 is the register and t2 is
6312            the memory reference */
6313         if (vtop[-1].r & VT_LVAL) {
6314             vswap();
6315             swapped = 1;
6316         }
6317         if (op >= TOK_ULT && op <= TOK_GT) {
6318             /* load on stack second operand */
6319             load(TREG_ST0, vtop);
6320             save_reg(TREG_EAX); /* eax is used by FP comparison code */
6321             if (op == TOK_GE || op == TOK_GT)
6322                 swapped = !swapped;
6323             else if (op == TOK_EQ || op == TOK_NE)
6324                 swapped = 0;
6325             if (swapped)
6326                 o(0xc9d9); /* fxch %st(1) */
6327             o(0xe9da); /* fucompp */
6328             o(0xe0df); /* fnstsw %ax */
6329             if (op == TOK_EQ) {
6330                 o(0x45e480); /* and $0x45, %ah */
6331                 o(0x40fC80); /* cmp $0x40, %ah */
6332             } else if (op == TOK_NE) {
6333                 o(0x45e480); /* and $0x45, %ah */
6334                 o(0x40f480); /* xor $0x40, %ah */
6335                 op = TOK_NE;
6336             } else if (op == TOK_GE || op == TOK_LE) {
6337                 o(0x05c4f6); /* test $0x05, %ah */
6338                 op = TOK_EQ;
6339             } else {
6340                 o(0x45c4f6); /* test $0x45, %ah */
6341                 op = TOK_EQ;
6342             }
6343             vtop--;
6344             vtop->r = VT_CMP;
6345             vtop->c.i = op;
6346         } else {
6347             /* no memory reference possible for long double operations */
6348             if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
6349                 load(TREG_ST0, vtop);
6350                 swapped = !swapped;
6351             }
6352             
6353             switch(op) {
6354             default:
6355             case '+':
6356                 a = 0;
6357                 break;
6358             case '-':
6359                 a = 4;
6360                 if (swapped)
6361                     a++;
6362                 break;
6363             case '*':
6364                 a = 1;
6365                 break;
6366             case '/':
6367                 a = 6;
6368                 if (swapped)
6369                     a++;
6370                 break;
6371             }
6372             ft = vtop->type.t;
6373             fc = vtop->c.ul;
6374             if ((ft & VT_BTYPE) == VT_LDOUBLE) {
6375                 o(0xde); /* fxxxp %st, %st(1) */
6376                 o(0xc1 + (a << 3));
6377             } else {
6378                 /* if saved lvalue, then we must reload it */
6379                 r = vtop->r;
6380                 if ((r & VT_VALMASK) == VT_LLOCAL) {
6381                     SValue v1;
6382                     r = get_reg(RC_INT);
6383                     v1.type.t = VT_INT;
6384                     v1.r = VT_LOCAL | VT_LVAL;
6385                     v1.c.ul = fc;
6386                     load(r, &v1);
6387                     fc = 0;
6388                 }
6389     
6390                 if ((ft & VT_BTYPE) == VT_DOUBLE)
6391                     o(0xdc);
6392                 else
6393                     o(0xd8);
6394                 gen_modrm(a, r, vtop->sym, fc);
6395             }
6396             vtop--;
6397         }
6398     }
6399     
6400     /* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
6401        and 'long long' cases. */
6402     void gen_cvt_itof(int t)
6403     {
6404         save_reg(TREG_ST0);
6405         gv(RC_INT);
6406         if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
6407             /* signed long long to float/double/long double (unsigned case
6408                is handled generically) */
6409             o(0x50 + vtop->r2); /* push r2 */
6410             o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
6411             o(0x242cdf); /* fildll (%esp) */
6412             o(0x08c483); /* add $8, %esp */
6413         } else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == 
6414                    (VT_INT | VT_UNSIGNED)) {
6415             /* unsigned int to float/double/long double */
6416             o(0x6a); /* push $0 */
6417             g(0x00);
6418             o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
6419             o(0x242cdf); /* fildll (%esp) */
6420             o(0x08c483); /* add $8, %esp */
6421         } else {
6422             /* int to float/double/long double */
6423             o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
6424             o(0x2404db); /* fildl (%esp) */
6425             o(0x04c483); /* add $4, %esp */
6426         }
6427         vtop->r = TREG_ST0;
6428     }
6429     
6430     /* convert fp to int 't' type */
6431     /* XXX: handle long long case */
6432     void gen_cvt_ftoi(int t)
6433     {
6434         int r, r2, size;
6435         Sym *sym;
6436         CType ushort_type;
6437     
6438         ushort_type.t = VT_SHORT | VT_UNSIGNED;
6439     
6440         gv(RC_FLOAT);
6441         if (t != VT_INT)
6442             size = 8;
6443         else 
6444             size = 4;
6445         
6446         o(0x2dd9); /* ldcw xxx */
6447         sym = external_global_sym(TOK___tcc_int_fpu_control, 
6448                                   &ushort_type, VT_LVAL);
6449         greloc(cur_text_section, sym, 
6450                ind, R_386_32);
6451         gen_le32(0);
6452         
6453         oad(0xec81, size); /* sub $xxx, %esp */
6454         if (size == 4)
6455             o(0x1cdb); /* fistpl */
6456         else
6457             o(0x3cdf); /* fistpll */
6458         o(0x24);
6459         o(0x2dd9); /* ldcw xxx */
6460         sym = external_global_sym(TOK___tcc_fpu_control, 
6461                                   &ushort_type, VT_LVAL);
6462         greloc(cur_text_section, sym, 
6463                ind, R_386_32);
6464         gen_le32(0);
6465     
6466         r = get_reg(RC_INT);
6467         o(0x58 + r); /* pop r */
6468         if (size == 8) {
6469             if (t == VT_LLONG) {
6470                 vtop->r = r; /* mark reg as used */
6471                 r2 = get_reg(RC_INT);
6472                 o(0x58 + r2); /* pop r2 */
6473                 vtop->r2 = r2;
6474             } else {
6475                 o(0x04c483); /* add $4, %esp */
6476             }
6477         }
6478         vtop->r = r;
6479     }
6480     
6481     /* convert from one floating point type to another */
6482     void gen_cvt_ftof(int t)
6483     {
6484         /* all we have to do on i386 is to put the float in a register */
6485         gv(RC_FLOAT);
6486     }
6487     
6488     /* computed goto support */
6489     void ggoto(void)
6490     {
6491         gcall_or_jmp(1);
6492         vtop--;
6493     }
6494     
6495     /* bound check support functions */
6496     #ifdef CONFIG_TCC_BCHECK
6497     
6498     /* generate a bounded pointer addition */
6499     void gen_bounded_ptr_add(void)
6500     {
6501         Sym *sym;
6502     
6503         /* prepare fast i386 function call (args in eax and edx) */
6504         gv2(RC_EAX, RC_EDX);
6505         /* save all temporary registers */
6506         vtop -= 2;
6507         save_regs(0);
6508         /* do a fast function call */
6509         sym = external_global_sym(TOK___bound_ptr_add, &func_old_type, 0);
6510         greloc(cur_text_section, sym, 
6511                ind + 1, R_386_PC32);
6512         oad(0xe8, -4);
6513         /* returned pointer is in eax */
6514         vtop++;
6515         vtop->r = TREG_EAX | VT_BOUNDED;
6516         /* address of bounding function call point */
6517         vtop->c.ul = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel)); 
6518     }
6519     
6520     /* patch pointer addition in vtop so that pointer dereferencing is
6521        also tested */
6522     void gen_bounded_ptr_deref(void)
6523     {
6524         int func;
6525         int size, align;
6526         Elf32_Rel *rel;
6527         Sym *sym;
6528     
6529         size = 0;
6530         /* XXX: put that code in generic part of tcc */
6531         if (!is_float(vtop->type.t)) {
6532             if (vtop->r & VT_LVAL_BYTE)
6533                 size = 1;
6534             else if (vtop->r & VT_LVAL_SHORT)
6535                 size = 2;
6536         }
6537         if (!size)
6538             size = type_size(&vtop->type, &align);
6539         switch(size) {
6540         case  1: func = TOK___bound_ptr_indir1; break;
6541         case  2: func = TOK___bound_ptr_indir2; break;
6542         case  4: func = TOK___bound_ptr_indir4; break;
6543         case  8: func = TOK___bound_ptr_indir8; break;
6544         case 12: func = TOK___bound_ptr_indir12; break;
6545         case 16: func = TOK___bound_ptr_indir16; break;
6546         default:
6547             error("unhandled size when derefencing bounded pointer");
6548             func = 0;
6549             break;
6550         }
6551     
6552         /* patch relocation */
6553         /* XXX: find a better solution ? */
6554         rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.ul);
6555         sym = external_global_sym(func, &func_old_type, 0);
6556         if (!sym->c)
6557             put_extern_sym(sym, NULL, 0, 0);
6558         rel->r_info = ELF32_R_INFO(sym->c, ELF32_R_TYPE(rel->r_info));
6559     }
6560     #endif
6561     
6562     /* end of X86 code generator */
6563     /*************************************************************/
6564     
6565     //---------------------------------------------------------------------------
6566     #endif
6567     
6568     // njn: commented these out
6569     //#ifdef TCC_TARGET_ARM
6570     //#include "arm-gen.c"
6571     //#endif
6572     //
6573     //#ifdef TCC_TARGET_C67
6574     //#include "c67-gen.c"
6575     //#endif
6576     
6577     #ifdef CONFIG_TCC_STATIC
6578     
6579     #define RTLD_LAZY       0x001
6580     #define RTLD_NOW        0x002
6581     #define RTLD_GLOBAL     0x100
6582     #define RTLD_DEFAULT    NULL
6583     
6584     /* dummy function for profiling */
6585     void *dlopen(const char *filename, int flag)
6586     {
6587         return NULL;
6588     }
6589     
6590     const char *dlerror(void)
6591     {
6592         return "error";
6593     }
6594     
6595     typedef struct TCCSyms {
6596         char *str;
6597         void *ptr;
6598     } TCCSyms;
6599     
6600     #define TCCSYM(a) { #a, &a, },
6601     
6602     /* add the symbol you want here if no dynamic linking is done */
6603     static TCCSyms tcc_syms[] = {
6604     #if !defined(CONFIG_TCCBOOT)
6605         TCCSYM(printf)
6606         TCCSYM(fprintf)
6607         TCCSYM(fopen)
6608         TCCSYM(fclose)
6609     #endif
6610         { NULL, NULL },
6611     };
6612     
6613     void *resolve_sym(TCCState *s1, const char *symbol, int type)
6614     {
6615         TCCSyms *p;
6616         p = tcc_syms;
6617         while (p->str != NULL) {
6618             if (!strcmp(p->str, symbol))
6619                 return p->ptr;
6620             p++;
6621         }
6622         return NULL;
6623     }
6624     
6625     #elif !defined(WIN32)
6626     
6627     #include <dlfcn.h>
6628     
6629     void *resolve_sym(TCCState *s1, const char *sym, int type)
6630     {
6631       assert(0);
6632       return 0; //dlsym(RTLD_DEFAULT, sym);
6633       // jrs: remove need for dlsym
6634     }
6635     
6636     #endif
6637     
6638     /********************************************************/
6639     
6640     /* we use our own 'finite' function to avoid potential problems with
6641        non standard math libs */
6642     /* XXX: endianness dependent */
6643     int ieee_finite(double d)
6644     {
6645         int *p = (int *)&d;
6646         return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
6647     }
6648     
6649     /* copy a string and truncate it. */
6650     static char *pstrcpy(char *buf, int buf_size, const char *s)
6651     {
6652         char *q, *q_end;
6653         int c;
6654     
6655         if (buf_size > 0) {
6656             q = buf;
6657             q_end = buf + buf_size - 1;
6658             while (q < q_end) {
6659                 c = *s++;
6660                 if (c == '\0')
6661                     break;
6662                 *q++ = c;
6663             }
6664             *q = '\0';
6665         }
6666         return buf;
6667     }
6668     
6669     /* strcat and truncate. */
6670     static char *pstrcat(char *buf, int buf_size, const char *s)
6671     {
6672         int len;
6673         len = strlen(buf);
6674         if (len < buf_size) 
6675             pstrcpy(buf + len, buf_size - len, s);
6676         return buf;
6677     }
6678     
6679     static int strstart(const char *str, const char *val, const char **ptr)
6680     {
6681         const char *p, *q;
6682         p = str;
6683         q = val;
6684         while (*q != '\0') {
6685             if (*p != *q)
6686                 return 0;
6687             p++;
6688             q++;
6689         }
6690         if (ptr)
6691             *ptr = p;
6692         return 1;
6693     }
6694     
6695     /* memory management */
6696     #ifdef MEM_DEBUG
6697     int mem_cur_size;
6698     int mem_max_size;
6699     #endif
6700     
6701     static inline void tcc_free(void *ptr)
6702     {
6703     #ifdef MEM_DEBUG
6704         mem_cur_size -= malloc_usable_size(ptr);
6705     #endif
6706         free(ptr);
6707     }
6708     
6709     static void *tcc_malloc(unsigned long size)
6710     {
6711         void *ptr;
6712         ptr = malloc(size);
6713         if (!ptr && size)
6714             error("memory full");
6715     #ifdef MEM_DEBUG
6716         mem_cur_size += malloc_usable_size(ptr);
6717         if (mem_cur_size > mem_max_size)
6718             mem_max_size = mem_cur_size;
6719     #endif
6720         return ptr;
6721     }
6722     
6723     static void *tcc_mallocz(unsigned long size)
6724     {
6725         void *ptr;
6726         ptr = tcc_malloc(size);
6727         memset(ptr, 0, size);
6728         return ptr;
6729     }
6730     
6731     static inline void *tcc_realloc(void *ptr, unsigned long size)
6732     {
6733         void *ptr1;
6734     #ifdef MEM_DEBUG
6735         mem_cur_size -= malloc_usable_size(ptr);
6736     #endif
6737         ptr1 = realloc(ptr, size);
6738     #ifdef MEM_DEBUG
6739         /* NOTE: count not correct if alloc error, but not critical */
6740         mem_cur_size += malloc_usable_size(ptr1);
6741         if (mem_cur_size > mem_max_size)
6742             mem_max_size = mem_cur_size;
6743     #endif
6744         return ptr1;
6745     }
6746     
6747     static char *tcc_strdup(const char *str)
6748     {
6749         char *ptr;
6750         ptr = tcc_malloc(strlen(str) + 1);
6751         strcpy(ptr, str);
6752         return ptr;
6753     }
6754     
6755     #define free(p) use_tcc_free(p)
6756     #define malloc(s) use_tcc_malloc(s)
6757     #define realloc(p, s) use_tcc_realloc(p, s)
6758     
6759     static void dynarray_add(void ***ptab, int *nb_ptr, void *data)
6760     {
6761         int nb, nb_alloc;
6762         void **pp;
6763         
6764         nb = *nb_ptr;
6765         pp = *ptab;
6766         /* every power of two we double array size */
6767         if ((nb & (nb - 1)) == 0) {
6768             if (!nb)
6769                 nb_alloc = 1;
6770             else
6771                 nb_alloc = nb * 2;
6772             pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
6773             if (!pp)
6774                 error("memory full");
6775             *ptab = pp;
6776         }
6777         pp[nb++] = data;
6778         *nb_ptr = nb;
6779     }
6780     
6781     /* symbol allocator */
6782     static Sym *__sym_malloc(void)
6783     {
6784         Sym *sym_pool, *sym, *last_sym;
6785         int i;
6786     
6787         sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
6788     
6789         last_sym = sym_free_first;
6790         sym = sym_pool;
6791         for(i = 0; i < SYM_POOL_NB; i++) {
6792             sym->next = last_sym;
6793             last_sym = sym;
6794             sym++;
6795         }
6796         sym_free_first = last_sym;
6797         return last_sym;
6798     }
6799     
6800     static inline Sym *sym_malloc(void)
6801     {
6802         Sym *sym;
6803         sym = sym_free_first;
6804         if (!sym)
6805             sym = __sym_malloc();
6806         sym_free_first = sym->next;
6807         return sym;
6808     }
6809     
6810     static inline void sym_free(Sym *sym)
6811     {
6812         sym->next = sym_free_first;
6813         sym_free_first = sym;
6814     }
6815     
6816     Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
6817     {
6818         Section *sec;
6819     
6820         sec = tcc_mallocz(sizeof(Section) + strlen(name));
6821         strcpy(sec->name, name);
6822         sec->sh_type = sh_type;
6823         sec->sh_flags = sh_flags;
6824         switch(sh_type) {
6825         case SHT_HASH:
6826         case SHT_REL:
6827         case SHT_DYNSYM:
6828         case SHT_SYMTAB:
6829         case SHT_DYNAMIC:
6830             sec->sh_addralign = 4;
6831             break;
6832         case SHT_STRTAB:
6833             sec->sh_addralign = 1;
6834             break;
6835         default:
6836             sec->sh_addralign = 32; /* default conservative alignment */
6837             break;
6838         }
6839     
6840         /* only add section if not private */
6841         if (!(sh_flags & SHF_PRIVATE)) {
6842             sec->sh_num = s1->nb_sections;
6843             dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
6844         }
6845         return sec;
6846     }
6847     
6848     static void free_section(Section *s)
6849     {
6850         tcc_free(s->data);
6851         tcc_free(s);
6852     }
6853     
6854     /* realloc section and set its content to zero */
6855     static void section_realloc(Section *sec, unsigned long new_size)
6856     {
6857         unsigned long size;
6858         unsigned char *data;
6859         
6860         size = sec->data_allocated;
6861         if (size == 0)
6862             size = 1;
6863         while (size < new_size)
6864             size = size * 2;
6865         data = tcc_realloc(sec->data, size);
6866         if (!data)
6867             error("memory full");
6868         memset(data + sec->data_allocated, 0, size - sec->data_allocated);
6869         sec->data = data;
6870         sec->data_allocated = size;
6871     }
6872     
6873     /* reserve at least 'size' bytes in section 'sec' from
6874        sec->data_offset. */
6875     static void *section_ptr_add(Section *sec, unsigned long size)
6876     {
6877         unsigned long offset, offset1;
6878     
6879         offset = sec->data_offset;
6880         offset1 = offset + size;
6881         if (offset1 > sec->data_allocated)
6882             section_realloc(sec, offset1);
6883         sec->data_offset = offset1;
6884         return sec->data + offset;
6885     }
6886     
6887     /* return a reference to a section, and create it if it does not
6888        exists */
6889     Section *find_section(TCCState *s1, const char *name)
6890     {
6891         Section *sec;
6892         int i;
6893         for(i = 1; i < s1->nb_sections; i++) {
6894             sec = s1->sections[i];
6895             if (!strcmp(name, sec->name)) 
6896                 return sec;
6897         }
6898         /* sections are created as PROGBITS */
6899         return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
6900     }
6901     
6902     #define SECTION_ABS ((void *)1)
6903     
6904     /* update sym->c so that it points to an external symbol in section
6905        'section' with value 'value' */
6906     static void put_extern_sym2(Sym *sym, Section *section, 
6907                                 unsigned long value, unsigned long size,
6908                                 int can_add_underscore)
6909     {
6910         int sym_type, sym_bind, sh_num, info;
6911         Elf32_Sym *esym;
6912         const char *name;
6913         char buf1[256];
6914     
6915         if (section == NULL)
6916             sh_num = SHN_UNDEF;
6917         else if (section == SECTION_ABS) 
6918             sh_num = SHN_ABS;
6919         else
6920             sh_num = section->sh_num;
6921         if (!sym->c) {
6922             if ((sym->type.t & VT_BTYPE) == VT_FUNC)
6923                 sym_type = STT_FUNC;
6924             else
6925                 sym_type = STT_OBJECT;
6926             if (sym->type.t & VT_STATIC)
6927                 sym_bind = STB_LOCAL;
6928             else
6929                 sym_bind = STB_GLOBAL;
6930             
6931             name = get_tok_str(sym->v, NULL);
6932     #ifdef CONFIG_TCC_BCHECK
6933             if (do_bounds_check) {
6934                 char buf[32];
6935     
6936                 /* XXX: avoid doing that for statics ? */
6937                 /* if bound checking is activated, we change some function
6938                    names by adding the "__bound" prefix */
6939                 switch(sym->v) {
6940     #if 0
6941                 /* XXX: we rely only on malloc hooks */
6942                 case TOK_malloc: 
6943                 case TOK_free: 
6944                 case TOK_realloc: 
6945                 case TOK_memalign: 
6946                 case TOK_calloc: 
6947     #endif
6948                 case TOK_memcpy: 
6949                 case TOK_memmove:
6950                 case TOK_memset:
6951                 case TOK_strlen:
6952                 case TOK_strcpy:
6953                     strcpy(buf, "__bound_");
6954                     strcat(buf, name);
6955                     name = buf;
6956                     break;
6957                 }
6958             }
6959     #endif
6960             if (tcc_state->leading_underscore && can_add_underscore) {
6961                 buf1[0] = '_';
6962                 pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
6963                 name = buf1;
6964             }
6965             info = ELF32_ST_INFO(sym_bind, sym_type);
6966             sym->c = add_elf_sym(symtab_section, value, size, info, 0, sh_num, name);
6967         } else {
6968             esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
6969             esym->st_value = value;
6970             esym->st_size = size;
6971             esym->st_shndx = sh_num;
6972         }
6973     }
6974     
6975     static void put_extern_sym(Sym *sym, Section *section, 
6976                                unsigned long value, unsigned long size)
6977     {
6978         put_extern_sym2(sym, section, value, size, 1);
6979     }
6980     
6981     /* add a new relocation entry to symbol 'sym' in section 's' */
6982     static void greloc(Section *s, Sym *sym, unsigned long offset, int type)
6983     {
6984         if (!sym->c) 
6985             put_extern_sym(sym, NULL, 0, 0);
6986         /* now we can add ELF relocation info */
6987         put_elf_reloc(symtab_section, s, offset, type, sym->c);
6988     }
6989     
6990     static inline int isid(int c)
6991     {
6992         return (c >= 'a' && c <= 'z') ||
6993             (c >= 'A' && c <= 'Z') ||
6994             c == '_';
6995     }
6996     
6997     static inline int isnum(int c)
6998     {
6999         return c >= '0' && c <= '9';
7000     }
7001     
7002     static inline int isoct(int c)
7003     {
7004         return c >= '0' && c <= '7';
7005     }
7006     
7007     static inline int toup(int c)
7008     {
7009         if (c >= 'a' && c <= 'z')
7010             return c - 'a' + 'A';
7011         else
7012             return c;
7013     }
7014     
7015     static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
7016     {
7017         int len;
7018         len = strlen(buf);
7019         vsnprintf(buf + len, buf_size - len, fmt, ap);
7020     }
7021     
7022     static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
7023     {
7024         va_list ap;
7025         va_start(ap, fmt);
7026         strcat_vprintf(buf, buf_size, fmt, ap);
7027         va_end(ap);
7028     }
7029     
7030     void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
7031     {
7032         char buf[2048];
7033         BufferedFile **f;
7034         
7035         buf[0] = '\0';
7036         if (file) {
7037             for(f = s1->include_stack; f < s1->include_stack_ptr; f++)
7038                 strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n", 
7039                               (*f)->filename, (*f)->line_num);
7040             if (file->line_num > 0) {
7041                 strcat_printf(buf, sizeof(buf), 
7042                               "%s:%d: ", file->filename, file->line_num);
7043             } else {
7044                 strcat_printf(buf, sizeof(buf),
7045                               "%s: ", file->filename);
7046             }
7047         } else {
7048             strcat_printf(buf, sizeof(buf),
7049                           "tcc: ");
7050         }
7051         if (is_warning)
7052             strcat_printf(buf, sizeof(buf), "warning: ");
7053         strcat_vprintf(buf, sizeof(buf), fmt, ap);
7054     
7055         if (!s1->error_func) {
7056             /* default case: stderr */
7057             fprintf(stderr, "%s\n", buf);
7058         } else {
7059             s1->error_func(s1->error_opaque, buf);
7060         }
7061         if (!is_warning || s1->warn_error)
7062             s1->nb_errors++;
7063     }
7064     
7065     #ifdef LIBTCC
7066     void tcc_set_error_func(TCCState *s, void *error_opaque,
7067                             void (*error_func)(void *opaque, const char *msg))
7068     {
7069         s->error_opaque = error_opaque;
7070         s->error_func = error_func;
7071     }
7072     #endif
7073     
7074     /* error without aborting current compilation */
7075     void error_noabort(const char *fmt, ...)
7076     {
7077         TCCState *s1 = tcc_state;
7078         va_list ap;
7079     
7080         va_start(ap, fmt);
7081         error1(s1, 0, fmt, ap);
7082         va_end(ap);
7083     }
7084     
7085     void error(const char *fmt, ...)
7086     {
7087         TCCState *s1 = tcc_state;
7088         va_list ap;
7089     
7090         va_start(ap, fmt);
7091         error1(s1, 0, fmt, ap);
7092         va_end(ap);
7093         /* better than nothing: in some cases, we accept to handle errors */
7094         if (s1->error_set_jmp_enabled) {
7095             longjmp(s1->error_jmp_buf, 1);
7096         } else {
7097             /* XXX: eliminate this someday */
7098             exit(1);
7099         }
7100     }
7101     
7102     void expect(const char *msg)
7103     {
7104         error("%s expected", msg);
7105     }
7106     
7107     void warning(const char *fmt, ...)
7108     {
7109         TCCState *s1 = tcc_state;
7110         va_list ap;
7111     
7112         if (s1->warn_none)
7113             return;
7114     
7115         va_start(ap, fmt);
7116         error1(s1, 1, fmt, ap);
7117         va_end(ap);
7118     }
7119     
7120     void skip(int c)
7121     {
7122         if (tok != c)
7123             error("'%c' expected", c);
7124         next();
7125     }
7126     
7127     static void test_lvalue(void)
7128     {
7129         if (!(vtop->r & VT_LVAL))
7130             expect("lvalue");
7131     }
7132     
7133     /* allocate a new token */
7134     static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
7135     {
7136         TokenSym *ts, **ptable;
7137         int i;
7138     
7139         if (tok_ident >= SYM_FIRST_ANOM) 
7140             error("memory full");
7141     
7142         /* expand token table if needed */
7143         i = tok_ident - TOK_IDENT;
7144         if ((i % TOK_ALLOC_INCR) == 0) {
7145             ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
7146             if (!ptable)
7147                 error("memory full");
7148             table_ident = ptable;
7149         }
7150     
7151         ts = tcc_malloc(sizeof(TokenSym) + len);
7152         table_ident[i] = ts;
7153         ts->tok = tok_ident++;
7154         ts->sym_define = NULL;
7155         ts->sym_label = NULL;
7156         ts->sym_struct = NULL;
7157         ts->sym_identifier = NULL;
7158         ts->len = len;
7159         ts->hash_next = NULL;
7160         memcpy(ts->str, str, len);
7161         ts->str[len] = '\0';
7162         *pts = ts;
7163         return ts;
7164     }
7165     
7166     #define TOK_HASH_INIT 1
7167     #define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
7168     
7169     /* find a token and add it if not found */
7170     static TokenSym *tok_alloc(const char *str, int len)
7171     {
7172         TokenSym *ts, **pts;
7173         int i;
7174         unsigned int h;
7175         
7176         h = TOK_HASH_INIT;
7177         for(i=0;i<len;i++)
7178             h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]);
7179         h &= (TOK_HASH_SIZE - 1);
7180     
7181         pts = &hash_ident[h];
7182         for(;;) {
7183             ts = *pts;
7184             if (!ts)
7185                 break;
7186             if (ts->len == len && !memcmp(ts->str, str, len))
7187                 return ts;
7188             pts = &(ts->hash_next);
7189         }
7190         return tok_alloc_new(pts, str, len);
7191     }
7192     
7193     /* CString handling */
7194     
7195     static void cstr_realloc(CString *cstr, int new_size)
7196     {
7197         int size;
7198         void *data;
7199     
7200         size = cstr->size_allocated;
7201         if (size == 0)
7202             size = 8; /* no need to allocate a too small first string */
7203         while (size < new_size)
7204             size = size * 2;
7205         data = tcc_realloc(cstr->data_allocated, size);
7206         if (!data)
7207             error("memory full");
7208         cstr->data_allocated = data;
7209         cstr->size_allocated = size;
7210         cstr->data = data;
7211     }
7212     
7213     /* add a byte */
7214     static inline void cstr_ccat(CString *cstr, int ch)
7215     {
7216         int size;
7217         size = cstr->size + 1;
7218         if (size > cstr->size_allocated)
7219             cstr_realloc(cstr, size);
7220         ((unsigned char *)cstr->data)[size - 1] = ch;
7221         cstr->size = size;
7222     }
7223     
7224     static void cstr_cat(CString *cstr, const char *str)
7225     {
7226         int c;
7227         for(;;) {
7228             c = *str;
7229             if (c == '\0')
7230                 break;
7231             cstr_ccat(cstr, c);
7232             str++;
7233         }
7234     }
7235     
7236     /* add a wide char */
7237     static void cstr_wccat(CString *cstr, int ch)
7238     {
7239         int size;
7240         size = cstr->size + sizeof(int);
7241         if (size > cstr->size_allocated)
7242             cstr_realloc(cstr, size);
7243         *(int *)(((unsigned char *)cstr->data) + size - sizeof(int)) = ch;
7244         cstr->size = size;
7245     }
7246     
7247     static void cstr_new(CString *cstr)
7248     {
7249         memset(cstr, 0, sizeof(CString));
7250     }
7251     
7252     /* free string and reset it to NULL */
7253     static void cstr_free(CString *cstr)
7254     {
7255         tcc_free(cstr->data_allocated);
7256         cstr_new(cstr);
7257     }
7258     
7259     #define cstr_reset(cstr) cstr_free(cstr)
7260     
7261     /* XXX: unicode ? */
7262     static void add_char(CString *cstr, int c)
7263     {
7264         if (c == '\'' || c == '\"' || c == '\\') {
7265             /* XXX: could be more precise if char or string */
7266             cstr_ccat(cstr, '\\');
7267         }
7268         if (c >= 32 && c <= 126) {
7269             cstr_ccat(cstr, c);
7270         } else {
7271             cstr_ccat(cstr, '\\');
7272             if (c == '\n') {
7273                 cstr_ccat(cstr, 'n');
7274             } else {
7275                 cstr_ccat(cstr, '0' + ((c >> 6) & 7));
7276                 cstr_ccat(cstr, '0' + ((c >> 3) & 7));
7277                 cstr_ccat(cstr, '0' + (c & 7));
7278             }
7279         }
7280     }
7281     
7282     /* XXX: buffer overflow */
7283     /* XXX: float tokens */
7284     char *get_tok_str(int v, CValue *cv)
7285     {
7286         static char buf[STRING_MAX_SIZE + 1];
7287         static CString cstr_buf;
7288         CString *cstr;
7289         unsigned char *q;
7290         char *p;
7291         int i, len;
7292     
7293         /* NOTE: to go faster, we give a fixed buffer for small strings */
7294         cstr_reset(&cstr_buf);
7295         cstr_buf.data = buf;
7296         cstr_buf.size_allocated = sizeof(buf);
7297         p = buf;
7298     
7299         switch(v) {
7300         case TOK_CINT:
7301         case TOK_CUINT:
7302             /* XXX: not quite exact, but only useful for testing */
7303             sprintf(p, "%u", cv->ui);
7304             break;
7305         case TOK_CLLONG:
7306         case TOK_CULLONG:
7307             /* XXX: not quite exact, but only useful for testing  */
7308             sprintf(p, "%Lu", cv->ull);
7309             break;
7310         case TOK_CCHAR:
7311         case TOK_LCHAR:
7312             cstr_ccat(&cstr_buf, '\'');
7313             add_char(&cstr_buf, cv->i);
7314             cstr_ccat(&cstr_buf, '\'');
7315             cstr_ccat(&cstr_buf, '\0');
7316             break;
7317         case TOK_PPNUM:
7318             cstr = cv->cstr;
7319             len = cstr->size - 1;
7320             for(i=0;i<len;i++)
7321                 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
7322             cstr_ccat(&cstr_buf, '\0');
7323             break;
7324         case TOK_STR:
7325         case TOK_LSTR:
7326             cstr = cv->cstr;
7327             cstr_ccat(&cstr_buf, '\"');
7328             if (v == TOK_STR) {
7329                 len = cstr->size - 1;
7330                 for(i=0;i<len;i++)
7331                     add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
7332             } else {
7333                 len = (cstr->size / sizeof(int)) - 1;
7334                 for(i=0;i<len;i++)
7335                     add_char(&cstr_buf, ((int *)cstr->data)[i]);
7336             }
7337             cstr_ccat(&cstr_buf, '\"');
7338             cstr_ccat(&cstr_buf, '\0');
7339             break;
7340         case TOK_LT:
7341             v = '<';
7342             goto addv;
7343         case TOK_GT:
7344             v = '>';
7345             goto addv;
7346         case TOK_A_SHL:
7347             return strcpy(p, "<<=");
7348         case TOK_A_SAR:
7349             return strcpy(p, ">>=");
7350         default:
7351             if (v < TOK_IDENT) {
7352                 /* search in two bytes table */
7353                 q = tok_two_chars;
7354                 while (*q) {
7355                     if (q[2] == v) {
7356                         *p++ = q[0];
7357                         *p++ = q[1];
7358                         *p = '\0';
7359                         return buf;
7360                     }
7361                     q += 3;
7362                 }
7363             addv:
7364                 *p++ = v;
7365                 *p = '\0';
7366             } else if (v < tok_ident) {
7367                 return table_ident[v - TOK_IDENT]->str;
7368             } else if (v >= SYM_FIRST_ANOM) {
7369                 /* special name for anonymous symbol */
7370                 sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
7371             } else {
7372                 /* should never happen */
7373                 return NULL;
7374             }
7375             break;
7376         }
7377         return cstr_buf.data;
7378     }
7379     
7380     /* push, without hashing */
7381     static Sym *sym_push2(Sym **ps, long v, long t, long c)
7382     {
7383         Sym *s;
7384         s = sym_malloc();
7385         s->v = v;
7386         s->type.t = t;
7387         s->c = c;
7388         s->next = NULL;
7389         /* add in stack */
7390         s->prev = *ps;
7391         *ps = s;
7392         return s;
7393     }
7394     
7395     /* find a symbol and return its associated structure. 's' is the top
7396        of the symbol stack */
7397     static Sym *sym_find2(Sym *s, int v)
7398     {
7399         while (s) {
7400             if (s->v == v)
7401                 return s;
7402             s = s->prev;
7403         }
7404         return NULL;
7405     }
7406     
7407     /* structure lookup */
7408     static inline Sym *struct_find(int v)
7409     {
7410         v -= TOK_IDENT;
7411         if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
7412             return NULL;
7413         return table_ident[v]->sym_struct;
7414     }
7415     
7416     /* find an identifier */
7417     static inline Sym *sym_find(int v)
7418     {
7419         v -= TOK_IDENT;
7420         if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
7421             return NULL;
7422         return table_ident[v]->sym_identifier;
7423     }
7424     
7425     /* push a given symbol on the symbol stack */
7426     static Sym *sym_push(int v, CType *type, int r, int c)
7427     {
7428         Sym *s, **ps;
7429         TokenSym *ts;
7430     
7431         if (local_stack)
7432             ps = &local_stack;
7433         else
7434             ps = &global_stack;
7435         s = sym_push2(ps, v, type->t, c);
7436         s->type.ref = type->ref;
7437         s->r = r;
7438         /* don't record fields or anonymous symbols */
7439         /* XXX: simplify */
7440         if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
7441             /* record symbol in token array */
7442             ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
7443             if (v & SYM_STRUCT)
7444                 ps = &ts->sym_struct;
7445             else
7446                 ps = &ts->sym_identifier;
7447             s->prev_tok = *ps;
7448             *ps = s;
7449         }
7450         return s;
7451     }
7452     
7453     /* push a global identifier */
7454     static Sym *global_identifier_push(int v, int t, int c)
7455     {
7456         Sym *s, **ps;
7457         s = sym_push2(&global_stack, v, t, c);
7458         /* don't record anonymous symbol */
7459         if (v < SYM_FIRST_ANOM) {
7460             ps = &table_ident[v - TOK_IDENT]->sym_identifier;
7461             /* modify the top most local identifier, so that
7462                sym_identifier will point to 's' when popped */
7463             while (*ps != NULL)
7464                 ps = &(*ps)->prev_tok;
7465             s->prev_tok = NULL;
7466             *ps = s;
7467         }
7468         return s;
7469     }
7470     
7471     /* pop symbols until top reaches 'b' */
7472     static void sym_pop(Sym **ptop, Sym *b)
7473     {
7474         Sym *s, *ss, **ps;
7475         TokenSym *ts;
7476         int v;
7477     
7478         s = *ptop;
7479         while(s != b) {
7480             ss = s->prev;
7481             v = s->v;
7482             /* remove symbol in token array */
7483             /* XXX: simplify */
7484             if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
7485                 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
7486                 if (v & SYM_STRUCT)
7487                     ps = &ts->sym_struct;
7488                 else
7489                     ps = &ts->sym_identifier;
7490                 *ps = s->prev_tok;
7491             }
7492             sym_free(s);
7493             s = ss;
7494         }
7495         *ptop = b;
7496     }
7497     
7498     /* I/O layer */
7499     
7500     BufferedFile *tcc_open(TCCState *s1, const char *filename)
7501     {
7502         int fd;
7503         BufferedFile *bf;
7504     
7505         fd = open(filename, O_RDONLY | O_BINARY);
7506         if (fd < 0)
7507             return NULL;
7508         bf = tcc_malloc(sizeof(BufferedFile));
7509         if (!bf) {
7510             close(fd);
7511             return NULL;
7512         }
7513         bf->fd = fd;
7514         bf->buf_ptr = bf->buffer;
7515         bf->buf_end = bf->buffer;
7516         bf->buffer[0] = CH_EOB; /* put eob symbol */
7517         pstrcpy(bf->filename, sizeof(bf->filename), filename);
7518         bf->line_num = 1;
7519         bf->ifndef_macro = 0;
7520         bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
7521         //    printf("opening '%s'\n", filename);
7522         return bf;
7523     }
7524     
7525     void tcc_close(BufferedFile *bf)
7526     {
7527         total_lines += bf->line_num;
7528         close(bf->fd);
7529         tcc_free(bf);
7530     }
7531     
7532     /* fill input buffer and peek next char */
7533     static int tcc_peekc_slow(BufferedFile *bf)
7534     {
7535         int len;
7536         /* only tries to read if really end of buffer */
7537         if (bf->buf_ptr >= bf->buf_end) {
7538             if (bf->fd != -1) {
7539     #if defined(PARSE_DEBUG)
7540                 len = 8;
7541     #else
7542                 len = IO_BUF_SIZE;
7543     #endif
7544                 len = read(bf->fd, bf->buffer, len);
7545                 if (len < 0)
7546                     len = 0;
7547             } else {
7548                 len = 0;
7549             }
7550             total_bytes += len;
7551             bf->buf_ptr = bf->buffer;
7552             bf->buf_end = bf->buffer + len;
7553             *bf->buf_end = CH_EOB;
7554         }
7555         if (bf->buf_ptr < bf->buf_end) {
7556             return bf->buf_ptr[0];
7557         } else {
7558             bf->buf_ptr = bf->buf_end;
7559             return CH_EOF;
7560         }
7561     }
7562     
7563     /* return the current character, handling end of block if necessary
7564        (but not stray) */
7565     static int handle_eob(void)
7566     {
7567         return tcc_peekc_slow(file);
7568     }
7569     
7570     /* read next char from current input file and handle end of input buffer */
7571     static inline void inp(void)
7572     {
7573         ch = *(++(file->buf_ptr));
7574         /* end of buffer/file handling */
7575         if (ch == CH_EOB)
7576             ch = handle_eob();
7577     }
7578     
7579     /* handle '\[\r]\n' */
7580     static void handle_stray(void)
7581     {
7582         while (ch == '\\') {
7583             inp();
7584             if (ch == '\n') {
7585                 file->line_num++;
7586                 inp();
7587             } else if (ch == '\r') {
7588                 inp();
7589                 if (ch != '\n')
7590                     goto fail;
7591                 file->line_num++;
7592                 inp();
7593             } else {
7594             fail:
7595                 error("stray '\\' in program");
7596             }
7597         }
7598     }
7599     
7600     /* skip the stray and handle the \\n case. Output an error if
7601        incorrect char after the stray */
7602     static int handle_stray1(uint8_t *p)
7603     {
7604         int c;
7605     
7606         if (p >= file->buf_end) {
7607             file->buf_ptr = p;
7608             c = handle_eob();
7609             p = file->buf_ptr;
7610             if (c == '\\')
7611                 goto parse_stray;
7612         } else {
7613         parse_stray:
7614             file->buf_ptr = p;
7615             ch = *p;
7616             handle_stray();
7617             p = file->buf_ptr;
7618             c = *p;
7619         }
7620         return c;
7621     }
7622     
7623     /* handle just the EOB case, but not stray */
7624     #define PEEKC_EOB(c, p)\
7625     {\
7626         p++;\
7627         c = *p;\
7628         if (c == '\\') {\
7629             file->buf_ptr = p;\
7630             c = handle_eob();\
7631             p = file->buf_ptr;\
7632         }\
7633     }
7634     
7635     /* handle the complicated stray case */
7636     #define PEEKC(c, p)\
7637     {\
7638         p++;\
7639         c = *p;\
7640         if (c == '\\') {\
7641             c = handle_stray1(p);\
7642             p = file->buf_ptr;\
7643         }\
7644     }
7645     
7646     /* input with '\[\r]\n' handling. Note that this function cannot
7647        handle other characters after '\', so you cannot call it inside
7648        strings or comments */
7649     static void minp(void)
7650     {
7651         inp();
7652         if (ch == '\\') 
7653             handle_stray();
7654     }
7655     
7656     
7657     /* single line C++ comments */
7658     static uint8_t *parse_line_comment(uint8_t *p)
7659     {
7660         int c;
7661     
7662         p++;
7663         for(;;) {
7664             c = *p;
7665         redo:
7666             if (c == '\n' || c == CH_EOF) {
7667                 break;
7668             } else if (c == '\\') {
7669                 file->buf_ptr = p;
7670                 c = handle_eob();
7671                 p = file->buf_ptr;
7672                 if (c == '\\') {
7673                     PEEKC_EOB(c, p);
7674                     if (c == '\n') {
7675                         file->line_num++;
7676                         PEEKC_EOB(c, p);
7677                     } else if (c == '\r') {
7678                         PEEKC_EOB(c, p);
7679                         if (c == '\n') {
7680                             file->line_num++;
7681                             PEEKC_EOB(c, p);
7682                         }
7683                     }
7684                 } else {
7685                     goto redo;
7686                 }
7687             } else {
7688                 p++;
7689             }
7690         }
7691         return p;
7692     }
7693     
7694     /* C comments */
7695     static uint8_t *parse_comment(uint8_t *p)
7696     {
7697         int c;
7698         
7699         p++;
7700         for(;;) {
7701             /* fast skip loop */
7702             for(;;) {
7703                 c = *p;
7704                 if (c == '\n' || c == '*' || c == '\\')
7705                     break;
7706                 p++;
7707                 c = *p;
7708                 if (c == '\n' || c == '*' || c == '\\')
7709                     break;
7710                 p++;
7711             }
7712             /* now we can handle all the cases */
7713             if (c == '\n') {
7714                 file->line_num++;
7715                 p++;
7716             } else if (c == '*') {
7717                 p++;
7718                 for(;;) {
7719                     c = *p;
7720                     if (c == '*') {
7721                         p++;
7722                     } else if (c == '/') {
7723                         goto end_of_comment;
7724                     } else if (c == '\\') {
7725                         file->buf_ptr = p;
7726                         c = handle_eob();
7727                         p = file->buf_ptr;
7728                         if (c == '\\') {
7729                             /* skip '\[\r]\n', otherwise just skip the stray */
7730                             while (c == '\\') {
7731                                 PEEKC_EOB(c, p);
7732                                 if (c == '\n') {
7733                                     file->line_num++;
7734                                     PEEKC_EOB(c, p);
7735                                 } else if (c == '\r') {
7736                                     PEEKC_EOB(c, p);
7737                                     if (c == '\n') {
7738                                         file->line_num++;
7739                                         PEEKC_EOB(c, p);
7740                                     }
7741                                 } else {
7742                                     goto after_star;
7743                                 }
7744                             }
7745                         }
7746                     } else {
7747                         break;
7748                     }
7749                 }
7750             after_star: ;
7751             } else {
7752                 /* stray, eob or eof */
7753                 file->buf_ptr = p;
7754                 c = handle_eob();
7755                 p = file->buf_ptr;
7756                 if (c == CH_EOF) {
7757                     error("unexpected end of file in comment");
7758                 } else if (c == '\\') {
7759                     p++;
7760                 }
7761             }
7762         }
7763      end_of_comment:
7764         p++;
7765         return p;
7766     }
7767     
7768     #define cinp minp
7769     
7770     /* space exlcuding newline */
7771     static inline int is_space(int ch)
7772     {
7773         return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
7774     }
7775     
7776     static inline void skip_spaces(void)
7777     {
7778         while (is_space(ch))
7779             cinp();
7780     }
7781     
7782     /* parse a string without interpreting escapes */
7783     static uint8_t *parse_pp_string(uint8_t *p,
7784                                     int sep, CString *str)
7785     {
7786         int c;
7787         p++;
7788         for(;;) {
7789             c = *p;
7790             if (c == sep) {
7791                 break;
7792             } else if (c == '\\') {
7793                 file->buf_ptr = p;
7794                 c = handle_eob();
7795                 p = file->buf_ptr;
7796                 if (c == CH_EOF) {
7797                 unterminated_string:
7798                     /* XXX: indicate line number of start of string */
7799                     error("missing terminating %c character", sep);
7800                 } else if (c == '\\') {
7801                     /* escape : just skip \[\r]\n */
7802                     PEEKC_EOB(c, p);
7803                     if (c == '\n') {
7804                         file->line_num++;
7805                         p++;
7806                     } else if (c == '\r') {
7807                         PEEKC_EOB(c, p);
7808                         if (c != '\n')
7809                             expect("'\n' after '\r'");
7810                         file->line_num++;
7811                         p++;
7812                     } else if (c == CH_EOF) {
7813                         goto unterminated_string;
7814                     } else {
7815                         if (str) {
7816                             cstr_ccat(str, '\\');
7817                             cstr_ccat(str, c);
7818                         }
7819                         p++;
7820                     }
7821                 }
7822             } else if (c == '\n') {
7823                 file->line_num++;
7824                 goto add_char;
7825             } else if (c == '\r') {
7826                 PEEKC_EOB(c, p);
7827                 if (c != '\n') {
7828                     if (str)
7829                         cstr_ccat(str, '\r');
7830                 } else {
7831                     file->line_num++;
7832                     goto add_char;
7833                 }
7834             } else {
7835             add_char:
7836                 if (str)
7837                     cstr_ccat(str, c);
7838                 p++;
7839             }
7840         }
7841         p++;
7842         return p;
7843     }
7844     
7845     /* skip block of text until #else, #elif or #endif. skip also pairs of
7846        #if/#endif */
7847     void preprocess_skip(void)
7848     {
7849         int a, start_of_line, c;
7850         uint8_t *p;
7851     
7852         p = file->buf_ptr;
7853         start_of_line = 1;
7854         a = 0;
7855         for(;;) {
7856         redo_no_start:
7857             c = *p;
7858             switch(c) {
7859             case ' ':
7860             case '\t':
7861             case '\f':
7862             case '\v':
7863             case '\r':
7864                 p++;
7865                 goto redo_no_start;
7866             case '\n':
7867                 start_of_line = 1;
7868                 file->line_num++;
7869                 p++;
7870                 goto redo_no_start;
7871             case '\\':
7872                 file->buf_ptr = p;
7873                 c = handle_eob();
7874                 if (c == CH_EOF) {
7875                     expect("#endif");
7876                 } else if (c == '\\') {
7877                     /* XXX: incorrect: should not give an error */
7878                     ch = file->buf_ptr[0];
7879                     handle_stray();
7880                 }
7881                 p = file->buf_ptr;
7882                 goto redo_no_start;
7883                 /* skip strings */
7884             case '\"':
7885             case '\'':
7886                 p = parse_pp_string(p, c, NULL);
7887                 break;
7888                 /* skip comments */
7889             case '/':
7890                 file->buf_ptr = p;
7891                 ch = *p;
7892                 minp();
7893                 p = file->buf_ptr;
7894                 if (ch == '*') {
7895                     p = parse_comment(p);
7896                 } else if (ch == '/') {
7897                     p = parse_line_comment(p);
7898                 }
7899                 break;
7900     
7901             case '#':
7902                 p++;
7903                 if (start_of_line) {
7904                     file->buf_ptr = p;
7905                     next_nomacro();
7906                     p = file->buf_ptr;
7907                     if (a == 0 && 
7908                         (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
7909                         goto the_end;
7910                     if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
7911                         a++;
7912                     else if (tok == TOK_ENDIF)
7913                         a--;
7914                 }
7915                 break;
7916             default:
7917                 p++;
7918                 break;
7919             }
7920             start_of_line = 0;
7921         }
7922      the_end: ;
7923         file->buf_ptr = p;
7924     }
7925     
7926     /* ParseState handling */
7927     
7928     /* XXX: currently, no include file info is stored. Thus, we cannot display
7929        accurate messages if the function or data definition spans multiple
7930        files */
7931     
7932     /* save current parse state in 's' */
7933     void save_parse_state(ParseState *s)
7934     {
7935         s->line_num = file->line_num;
7936         s->macro_ptr = macro_ptr;
7937         s->tok = tok;
7938         s->tokc = tokc;
7939     }
7940     
7941     /* restore parse state from 's' */
7942     void restore_parse_state(ParseState *s)
7943     {
7944         file->line_num = s->line_num;
7945         macro_ptr = s->macro_ptr;
7946         tok = s->tok;
7947         tokc = s->tokc;
7948     }
7949     
7950     /* return the number of additional 'ints' necessary to store the
7951        token */
7952     static inline int tok_ext_size(int t)
7953     {
7954         switch(t) {
7955             /* 4 bytes */
7956         case TOK_CINT:
7957         case TOK_CUINT:
7958         case TOK_CCHAR:
7959         case TOK_LCHAR:
7960         case TOK_CFLOAT:
7961         case TOK_LINENUM:
7962             return 1;
7963         case TOK_STR:
7964         case TOK_LSTR:
7965         case TOK_PPNUM:
7966             error("unsupported token");
7967             return 1;
7968         case TOK_CDOUBLE:
7969         case TOK_CLLONG:
7970         case TOK_CULLONG:
7971             return 2;
7972         case TOK_CLDOUBLE:
7973             return LDOUBLE_SIZE / 4;
7974         default:
7975             return 0;
7976         }
7977     }
7978     
7979     /* token string handling */
7980     
7981     static inline void tok_str_new(TokenString *s)
7982     {
7983         s->str = NULL;
7984         s->len = 0;
7985         s->allocated_len = 0;
7986         s->last_line_num = -1;
7987     }
7988     
7989     static void tok_str_free(int *str)
7990     {
7991         tcc_free(str);
7992     }
7993     
7994     static int *tok_str_realloc(TokenString *s)
7995     {
7996         int *str, len;
7997     
7998         if (s->allocated_len == 0) {
7999             len = 8;
8000         } else {
8001             len = s->allocated_len * 2;
8002         }
8003         str = tcc_realloc(s->str, len * sizeof(int));
8004         if (!str)
8005             error("memory full");
8006         s->allocated_len = len;
8007         s->str = str;
8008         return str;
8009     }
8010     
8011     static void tok_str_add(TokenString *s, int t)
8012     {
8013         int len, *str;
8014     
8015         len = s->len;
8016         str = s->str;
8017         if (len >= s->allocated_len)
8018             str = tok_str_realloc(s);
8019         str[len++] = t;
8020         s->len = len;
8021     }
8022     
8023     static void tok_str_add2(TokenString *s, int t, CValue *cv)
8024     {
8025         int len, *str;
8026     
8027         len = s->len;
8028         str = s->str;
8029     
8030         /* allocate space for worst case */
8031         if (len + TOK_MAX_SIZE > s->allocated_len)
8032             str = tok_str_realloc(s);
8033         str[len++] = t;
8034         switch(t) {
8035         case TOK_CINT:
8036         case TOK_CUINT:
8037         case TOK_CCHAR:
8038         case TOK_LCHAR:
8039         case TOK_CFLOAT:
8040         case TOK_LINENUM:
8041             str[len++] = cv->tab[0];
8042             break;
8043         case TOK_PPNUM:
8044         case TOK_STR:
8045         case TOK_LSTR:
8046             {
8047                 int nb_words;
8048                 CString *cstr;
8049     
8050                 nb_words = (sizeof(CString) + cv->cstr->size + 3) >> 2;
8051                 while ((len + nb_words) > s->allocated_len)
8052                     str = tok_str_realloc(s);
8053                 cstr = (CString *)(str + len);
8054                 cstr->data = NULL;
8055                 cstr->size = cv->cstr->size;
8056                 cstr->data_allocated = NULL;
8057                 cstr->size_allocated = cstr->size;
8058                 memcpy((char *)cstr + sizeof(CString), 
8059                        cv->cstr->data, cstr->size);
8060                 len += nb_words;
8061             }
8062             break;
8063         case TOK_CDOUBLE:
8064         case TOK_CLLONG:
8065         case TOK_CULLONG:
8066     #if LDOUBLE_SIZE == 8
8067         case TOK_CLDOUBLE:
8068     #endif
8069             str[len++] = cv->tab[0];
8070             str[len++] = cv->tab[1];
8071             break;
8072     #if LDOUBLE_SIZE == 12
8073         case TOK_CLDOUBLE:
8074             str[len++] = cv->tab[0];
8075             str[len++] = cv->tab[1];
8076             str[len++] = cv->tab[2];
8077     #elif LDOUBLE_SIZE != 8
8078     #error add long double size support
8079     #endif
8080             break;
8081         default:
8082             break;
8083         }
8084         s->len = len;
8085     }
8086     
8087     /* add the current parse token in token string 's' */
8088     static void tok_str_add_tok(TokenString *s)
8089     {
8090         CValue cval;
8091     
8092         /* save line number info */
8093         if (file->line_num != s->last_line_num) {
8094             s->last_line_num = file->line_num;
8095             cval.i = s->last_line_num;
8096             tok_str_add2(s, TOK_LINENUM, &cval);
8097         }
8098         tok_str_add2(s, tok, &tokc);
8099     }
8100     
8101     #if LDOUBLE_SIZE == 12
8102     #define LDOUBLE_GET(p, cv)                      \
8103             cv.tab[0] = p[0];                       \
8104             cv.tab[1] = p[1];                       \
8105             cv.tab[2] = p[2];
8106     #elif LDOUBLE_SIZE == 8
8107     #define LDOUBLE_GET(p, cv)                      \
8108             cv.tab[0] = p[0];                       \
8109             cv.tab[1] = p[1];
8110     #else
8111     #error add long double size support
8112     #endif
8113     
8114     
8115     /* get a token from an integer array and increment pointer
8116        accordingly. we code it as a macro to avoid pointer aliasing. */
8117     #define TOK_GET(t, p, cv)                       \
8118     {                                               \
8119         t = *p++;                                   \
8120         switch(t) {                                 \
8121         case TOK_CINT:                              \
8122         case TOK_CUINT:                             \
8123         case TOK_CCHAR:                             \
8124         case TOK_LCHAR:                             \
8125         case TOK_CFLOAT:                            \
8126         case TOK_LINENUM:                           \
8127             cv.tab[0] = *p++;                       \
8128             break;                                  \
8129         case TOK_STR:                               \
8130         case TOK_LSTR:                              \
8131         case TOK_PPNUM:                             \
8132             cv.cstr = (CString *)p;                 \
8133             cv.cstr->data = (char *)p + sizeof(CString);\
8134             p += (sizeof(CString) + cv.cstr->size + 3) >> 2;\
8135             break;                                  \
8136         case TOK_CDOUBLE:                           \
8137         case TOK_CLLONG:                            \
8138         case TOK_CULLONG:                           \
8139             cv.tab[0] = p[0];                       \
8140             cv.tab[1] = p[1];                       \
8141             p += 2;                                 \
8142             break;                                  \
8143         case TOK_CLDOUBLE:                          \
8144             LDOUBLE_GET(p, cv);                     \
8145             p += LDOUBLE_SIZE / 4;                  \
8146             break;                                  \
8147         default:                                    \
8148             break;                                  \
8149         }                                           \
8150     }
8151     
8152     /* defines handling */
8153     static inline void define_push(int v, int macro_type, int *str, Sym *first_arg)
8154     {
8155         Sym *s;
8156     
8157         s = sym_push2(&define_stack, v, macro_type, (long)str);
8158         s->next = first_arg;
8159         table_ident[v - TOK_IDENT]->sym_define = s;
8160     }
8161     
8162     /* undefined a define symbol. Its name is just set to zero */
8163     static void define_undef(Sym *s)
8164     {
8165         int v;
8166         v = s->v;
8167         if (v >= TOK_IDENT && v < tok_ident)
8168             table_ident[v - TOK_IDENT]->sym_define = NULL;
8169         s->v = 0;
8170     }
8171     
8172     static inline Sym *define_find(int v)
8173     {
8174         v -= TOK_IDENT;
8175         if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
8176             return NULL;
8177         return table_ident[v]->sym_define;
8178     }
8179     
8180     /* free define stack until top reaches 'b' */
8181     static void free_defines(Sym *b)
8182     {
8183         Sym *top, *top1;
8184         int v;
8185     
8186         top = define_stack;
8187         while (top != b) {
8188             top1 = top->prev;
8189             /* do not free args or predefined defines */
8190             if (top->c)
8191                 tok_str_free((int *)top->c);
8192             v = top->v;
8193             if (v >= TOK_IDENT && v < tok_ident)
8194                 table_ident[v - TOK_IDENT]->sym_define = NULL;
8195             sym_free(top);
8196             top = top1;
8197         }
8198         define_stack = b;
8199     }
8200     
8201     /* label lookup */
8202     static Sym *label_find(int v)
8203     {
8204         v -= TOK_IDENT;
8205         if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
8206             return NULL;
8207         return table_ident[v]->sym_label;
8208     }
8209     
8210     static Sym *label_push(Sym **ptop, int v, int flags)
8211     {
8212         Sym *s, **ps;
8213         s = sym_push2(ptop, v, 0, 0);
8214         s->r = flags;
8215         ps = &table_ident[v - TOK_IDENT]->sym_label;
8216         if (ptop == &global_label_stack) {
8217             /* modify the top most local identifier, so that
8218                sym_identifier will point to 's' when popped */
8219             while (*ps != NULL)
8220                 ps = &(*ps)->prev_tok;
8221         }
8222         s->prev_tok = *ps;
8223         *ps = s;
8224         return s;
8225     }
8226     
8227     /* pop labels until element last is reached. Look if any labels are
8228        undefined. Define symbols if '&&label' was used. */
8229     static void label_pop(Sym **ptop, Sym *slast)
8230     {
8231         Sym *s, *s1;
8232         for(s = *ptop; s != slast; s = s1) {
8233             s1 = s->prev;
8234             if (s->r == LABEL_DECLARED) {
8235                 warning("label '%s' declared but not used", get_tok_str(s->v, NULL));
8236             } else if (s->r == LABEL_FORWARD) {
8237                     error("label '%s' used but not defined",
8238                           get_tok_str(s->v, NULL));
8239             } else {
8240                 if (s->c) {
8241                     /* define corresponding symbol. A size of
8242                        1 is put. */
8243                     put_extern_sym(s, cur_text_section, (long)s->next, 1);
8244                 }
8245             }
8246             /* remove label */
8247             table_ident[s->v - TOK_IDENT]->sym_label = s->prev_tok;
8248             sym_free(s);
8249         }
8250         *ptop = slast;
8251     }
8252     
8253     /* eval an expression for #if/#elif */
8254     static int expr_preprocess(void)
8255     {
8256         int c, t;
8257         TokenString str;
8258         
8259         tok_str_new(&str);
8260         while (tok != TOK_LINEFEED && tok != TOK_EOF) {
8261             next(); /* do macro subst */
8262             if (tok == TOK_DEFINED) {
8263                 next_nomacro();
8264                 t = tok;
8265                 if (t == '(') 
8266                     next_nomacro();
8267                 c = define_find(tok) != 0;
8268                 if (t == '(')
8269                     next_nomacro();
8270                 tok = TOK_CINT;
8271                 tokc.i = c;
8272             } else if (tok >= TOK_IDENT) {
8273                 /* if undefined macro */
8274                 tok = TOK_CINT;
8275                 tokc.i = 0;
8276             }
8277             tok_str_add_tok(&str);
8278         }
8279         tok_str_add(&str, -1); /* simulate end of file */
8280         tok_str_add(&str, 0);
8281         /* now evaluate C constant expression */
8282         macro_ptr = str.str;
8283         next();
8284         c = expr_const();
8285         macro_ptr = NULL;
8286         tok_str_free(str.str);
8287         return c != 0;
8288     }
8289     
8290     #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
8291     static void tok_print(int *str)
8292     {
8293         int t;
8294         CValue cval;
8295     
8296         while (1) {
8297             TOK_GET(t, str, cval);
8298             if (!t)
8299                 break;
8300             printf(" %s", get_tok_str(t, &cval));
8301         }
8302         printf("\n");
8303     }
8304     #endif
8305     
8306     /* parse after #define */
8307     static void parse_define(void)
8308     {
8309         Sym *s, *first, **ps;
8310         int v, t, varg, is_vaargs, c;
8311         TokenString str;
8312         
8313         v = tok;
8314         if (v < TOK_IDENT)
8315             error("invalid macro name '%s'", get_tok_str(tok, &tokc));
8316         /* XXX: should check if same macro (ANSI) */
8317         first = NULL;
8318         t = MACRO_OBJ;
8319         /* '(' must be just after macro definition for MACRO_FUNC */
8320         c = file->buf_ptr[0];
8321         if (c == '\\')
8322             c = handle_stray1(file->buf_ptr);
8323         if (c == '(') {
8324             next_nomacro();
8325             next_nomacro();
8326             ps = &first;
8327             while (tok != ')') {
8328                 varg = tok;
8329                 next_nomacro();
8330                 is_vaargs = 0;
8331                 if (varg == TOK_DOTS) {
8332                     varg = TOK___VA_ARGS__;
8333                     is_vaargs = 1;
8334                 } else if (tok == TOK_DOTS && gnu_ext) {
8335                     is_vaargs = 1;
8336                     next_nomacro();
8337                 }
8338                 if (varg < TOK_IDENT)
8339                     error("badly punctuated parameter list");
8340                 s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
8341                 *ps = s;
8342                 ps = &s->next;
8343                 if (tok != ',')
8344                     break;
8345                 next_nomacro();
8346             }
8347             t = MACRO_FUNC;
8348         }
8349         tok_str_new(&str);
8350         next_nomacro();
8351         /* EOF testing necessary for '-D' handling */
8352         while (tok != TOK_LINEFEED && tok != TOK_EOF) {
8353             tok_str_add2(&str, tok, &tokc);
8354             next_nomacro();
8355         }
8356         tok_str_add(&str, 0);
8357     #ifdef PP_DEBUG
8358         printf("define %s %d: ", get_tok_str(v, NULL), t);
8359         tok_print(str.str);
8360     #endif
8361         define_push(v, t, str.str, first);
8362     }
8363     
8364     static inline int hash_cached_include(int type, const char *filename)
8365     {
8366         const unsigned char *s;
8367         unsigned int h;
8368     
8369         h = TOK_HASH_INIT;
8370         h = TOK_HASH_FUNC(h, type);
8371         s = filename;
8372         while (*s) {
8373             h = TOK_HASH_FUNC(h, *s);
8374             s++;
8375         }
8376         h &= (CACHED_INCLUDES_HASH_SIZE - 1);
8377         return h;
8378     }
8379     
8380     /* XXX: use a token or a hash table to accelerate matching ? */
8381     static CachedInclude *search_cached_include(TCCState *s1,
8382                                                 int type, const char *filename)
8383     {
8384         CachedInclude *e;
8385         int i, h;
8386         h = hash_cached_include(type, filename);
8387         i = s1->cached_includes_hash[h];
8388         for(;;) {
8389             if (i == 0)
8390                 break;
8391             e = s1->cached_includes[i - 1];
8392             if (e->type == type && !strcmp(e->filename, filename))
8393                 return e;
8394             i = e->hash_next;
8395         }
8396         return NULL;
8397     }
8398     
8399     static inline void add_cached_include(TCCState *s1, int type, 
8400                                           const char *filename, int ifndef_macro)
8401     {
8402         CachedInclude *e;
8403         int h;
8404     
8405         if (search_cached_include(s1, type, filename))
8406             return;
8407     #ifdef INC_DEBUG
8408         printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL));
8409     #endif
8410         e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
8411         if (!e)
8412             return;
8413         e->type = type;
8414         strcpy(e->filename, filename);
8415         e->ifndef_macro = ifndef_macro;
8416         dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e);
8417         /* add in hash table */
8418         h = hash_cached_include(type, filename);
8419         e->hash_next = s1->cached_includes_hash[h];
8420         s1->cached_includes_hash[h] = s1->nb_cached_includes;
8421     }
8422     
8423     static void pragma_parse(TCCState *s1)
8424     {
8425         int val;
8426     
8427         next();
8428         if (tok == TOK_pack) {
8429             /*
8430               This may be:
8431               #pragma pack(1) // set
8432               #pragma pack() // reset to default
8433               #pragma pack(push,1) // push & set
8434               #pragma pack(pop) // restore previous
8435             */
8436             next();
8437             skip('(');
8438             if (tok == TOK_ASM_pop) {
8439                 next();
8440                 if (s1->pack_stack_ptr <= s1->pack_stack) {
8441                 stk_error:
8442                     error("out of pack stack");
8443                 }
8444                 s1->pack_stack_ptr--;
8445             } else {
8446                 val = 0;
8447                 if (tok != ')') {
8448                     if (tok == TOK_ASM_push) {
8449                         next();
8450                         if (s1->pack_stack_ptr >= s1->pack_stack + PACK_STACK_SIZE - 1)
8451                             goto stk_error;
8452                         s1->pack_stack_ptr++;
8453                         skip(',');
8454                     }
8455                     if (tok != TOK_CINT) {
8456                     pack_error:
8457                         error("invalid pack pragma");
8458                     }
8459                     val = tokc.i;
8460                     if (val < 1 || val > 16 || (val & (val - 1)) != 0)
8461                         goto pack_error;
8462                     next();
8463                 }
8464                 *s1->pack_stack_ptr = val;
8465                 skip(')');
8466             }
8467         }
8468     }
8469     
8470     /* is_bof is true if first non space token at beginning of file */
8471     static void preprocess(int is_bof)
8472     {
8473         TCCState *s1 = tcc_state;
8474         int size, i, c, n, saved_parse_flags;
8475         char buf[1024], *q, *p;
8476         char buf1[1024];
8477         BufferedFile *f;
8478         Sym *s;
8479         CachedInclude *e;
8480         
8481         saved_parse_flags = parse_flags;
8482         parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | 
8483             PARSE_FLAG_LINEFEED;
8484         next_nomacro();
8485      redo:
8486         switch(tok) {
8487         case TOK_DEFINE:
8488             next_nomacro();
8489             parse_define();
8490             break;
8491         case TOK_UNDEF:
8492             next_nomacro();
8493             s = define_find(tok);
8494             /* undefine symbol by putting an invalid name */
8495             if (s)
8496                 define_undef(s);
8497             break;
8498         case TOK_INCLUDE:
8499         case TOK_INCLUDE_NEXT:
8500             ch = file->buf_ptr[0];
8501             /* XXX: incorrect if comments : use next_nomacro with a special mode */
8502             skip_spaces();
8503             if (ch == '<') {
8504                 c = '>';
8505                 goto read_name;
8506             } else if (ch == '\"') {
8507                 c = ch;
8508             read_name:
8509                 /* XXX: better stray handling */
8510                 minp();
8511                 q = buf;
8512                 while (ch != c && ch != '\n' && ch != CH_EOF) {
8513                     if ((q - buf) < sizeof(buf) - 1)
8514                         *q++ = ch;
8515                     minp();
8516                 }
8517                 *q = '\0';
8518                 minp();
8519     #if 0
8520                 /* eat all spaces and comments after include */
8521                 /* XXX: slightly incorrect */
8522                 while (ch1 != '\n' && ch1 != CH_EOF)
8523                     inp();
8524     #endif
8525             } else {
8526                 /* computed #include : either we have only strings or
8527                    we have anything enclosed in '<>' */
8528                 next();
8529                 buf[0] = '\0';
8530                 if (tok == TOK_STR) {
8531                     while (tok != TOK_LINEFEED) {
8532                         if (tok != TOK_STR) {
8533                         include_syntax:
8534                             error("'#include' expects \"FILENAME\" or <FILENAME>");
8535                         }
8536                         pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
8537                         next();
8538                     }
8539                     c = '\"';
8540                 } else {
8541                     int len;
8542                     while (tok != TOK_LINEFEED) {
8543                         pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
8544                         next();
8545                     }
8546                     len = strlen(buf);
8547                     /* check syntax and remove '<>' */
8548                     if (len < 2 || buf[0] != '<' || buf[len - 1] != '>')
8549                         goto include_syntax;
8550                     memmove(buf, buf + 1, len - 2);
8551                     buf[len - 2] = '\0';
8552                     c = '>';
8553                 }
8554             }
8555     
8556             e = search_cached_include(s1, c, buf);
8557             if (e && define_find(e->ifndef_macro)) {
8558                 /* no need to parse the include because the 'ifndef macro'
8559                    is defined */
8560     #ifdef INC_DEBUG
8561                 printf("%s: skipping %s\n", file->filename, buf);
8562     #endif
8563             } else {
8564                 if (c == '\"') {
8565                     /* first search in current dir if "header.h" */
8566                     size = 0;
8567                     p = strrchr(file->filename, '/');
8568                     if (p) 
8569                         size = p + 1 - file->filename;
8570                     if (size > sizeof(buf1) - 1)
8571                         size = sizeof(buf1) - 1;
8572                     memcpy(buf1, file->filename, size);
8573                     buf1[size] = '\0';
8574                     pstrcat(buf1, sizeof(buf1), buf);
8575                     f = tcc_open(s1, buf1);
8576                     if (f) {
8577                         if (tok == TOK_INCLUDE_NEXT)
8578                             tok = TOK_INCLUDE;
8579                         else
8580                             goto found;
8581                     }
8582                 }
8583                 if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
8584                     error("#include recursion too deep");
8585                 /* now search in all the include paths */
8586                 n = s1->nb_include_paths + s1->nb_sysinclude_paths;
8587                 for(i = 0; i < n; i++) {
8588                     const char *path;
8589                     if (i < s1->nb_include_paths)
8590                         path = s1->include_paths[i];
8591                     else
8592                         path = s1->sysinclude_paths[i - s1->nb_include_paths];
8593                     pstrcpy(buf1, sizeof(buf1), path);
8594                     pstrcat(buf1, sizeof(buf1), "/");
8595                     pstrcat(buf1, sizeof(buf1), buf);
8596                     f = tcc_open(s1, buf1);
8597                     if (f) {
8598                         if (tok == TOK_INCLUDE_NEXT)
8599                             tok = TOK_INCLUDE;
8600                         else
8601                             goto found;
8602                     }
8603                 }
8604                 error("include file '%s' not found", buf);
8605                 f = NULL;
8606             found:
8607     #ifdef INC_DEBUG
8608                 printf("%s: including %s\n", file->filename, buf1);
8609     #endif
8610                 f->inc_type = c;
8611                 pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf);
8612                 /* push current file in stack */
8613                 /* XXX: fix current line init */
8614                 *s1->include_stack_ptr++ = file;
8615                 file = f;
8616                 /* add include file debug info */
8617                 if (do_debug) {
8618                     put_stabs(file->filename, N_BINCL, 0, 0, 0);
8619                 }
8620                 tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL;
8621                 ch = file->buf_ptr[0];
8622                 goto the_end;
8623             }
8624             break;
8625         case TOK_IFNDEF:
8626             c = 1;
8627             goto do_ifdef;
8628         case TOK_IF:
8629             c = expr_preprocess();
8630             goto do_if;
8631         case TOK_IFDEF:
8632             c = 0;
8633         do_ifdef:
8634             next_nomacro();
8635             if (tok < TOK_IDENT)
8636                 error("invalid argument for '#if%sdef'", c ? "n" : "");
8637             if (is_bof) {
8638                 if (c) {
8639     #ifdef INC_DEBUG
8640                     printf("#ifndef %s\n", get_tok_str(tok, NULL));
8641     #endif
8642                     file->ifndef_macro = tok;
8643                 }
8644             }
8645             c = (define_find(tok) != 0) ^ c;
8646         do_if:
8647             if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
8648                 error("memory full");
8649             *s1->ifdef_stack_ptr++ = c;
8650             goto test_skip;
8651         case TOK_ELSE:
8652             if (s1->ifdef_stack_ptr == s1->ifdef_stack)
8653                 error("#else without matching #if");
8654             if (s1->ifdef_stack_ptr[-1] & 2)
8655                 error("#else after #else");
8656             c = (s1->ifdef_stack_ptr[-1] ^= 3);
8657             goto test_skip;
8658         case TOK_ELIF:
8659             if (s1->ifdef_stack_ptr == s1->ifdef_stack)
8660                 error("#elif without matching #if");
8661             c = s1->ifdef_stack_ptr[-1];
8662             if (c > 1)
8663                 error("#elif after #else");
8664             /* last #if/#elif expression was true: we skip */
8665             if (c == 1)
8666                 goto skip;
8667             c = expr_preprocess();
8668             s1->ifdef_stack_ptr[-1] = c;
8669         test_skip:
8670             if (!(c & 1)) {
8671             skip:
8672                 preprocess_skip();
8673                 is_bof = 0;
8674                 goto redo;
8675             }
8676             break;
8677         case TOK_ENDIF:
8678             if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
8679                 error("#endif without matching #if");
8680             s1->ifdef_stack_ptr--;
8681             /* '#ifndef macro' was at the start of file. Now we check if
8682                an '#endif' is exactly at the end of file */
8683             if (file->ifndef_macro &&
8684                 s1->ifdef_stack_ptr == file->ifdef_stack_ptr) {
8685                 file->ifndef_macro_saved = file->ifndef_macro;
8686                 /* need to set to zero to avoid false matches if another
8687                    #ifndef at middle of file */
8688                 file->ifndef_macro = 0;
8689                 while (tok != TOK_LINEFEED)
8690                     next_nomacro();
8691                 tok_flags |= TOK_FLAG_ENDIF;
8692                 goto the_end;
8693             }
8694             break;
8695         case TOK_LINE:
8696             next();
8697             if (tok != TOK_CINT)
8698                 error("#line");
8699             file->line_num = tokc.i - 1; /* the line number will be incremented after */
8700             next();
8701             if (tok != TOK_LINEFEED) {
8702                 if (tok != TOK_STR)
8703                     error("#line");
8704                 pstrcpy(file->filename, sizeof(file->filename), 
8705                         (char *)tokc.cstr->data);
8706             }
8707             break;
8708         case TOK_ERROR:
8709         case TOK_WARNING:
8710             c = tok;
8711             ch = file->buf_ptr[0];
8712             skip_spaces();
8713             q = buf;
8714             while (ch != '\n' && ch != CH_EOF) {
8715                 if ((q - buf) < sizeof(buf) - 1)
8716                     *q++ = ch;
8717                 minp();
8718             }
8719             *q = '\0';
8720             if (c == TOK_ERROR)
8721                 error("#error %s", buf);
8722             else
8723                 warning("#warning %s", buf);
8724             break;
8725         case TOK_PRAGMA:
8726             pragma_parse(s1);
8727             break;
8728         default:
8729             if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_CINT) {
8730                 /* '!' is ignored to allow C scripts. numbers are ignored
8731                    to emulate cpp behaviour */
8732             } else {
8733                 if (!(saved_parse_flags & PARSE_FLAG_ASM_COMMENTS))
8734                     error("invalid preprocessing directive #%s", get_tok_str(tok, &tokc));
8735             }
8736             break;
8737         }
8738         /* ignore other preprocess commands or #! for C scripts */
8739         while (tok != TOK_LINEFEED)
8740             next_nomacro();
8741      the_end:
8742         parse_flags = saved_parse_flags;
8743     }
8744     
8745     /* evaluate escape codes in a string. */
8746     static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long)
8747     {
8748         int c, n;
8749         const uint8_t *p;
8750     
8751         p = buf;
8752         for(;;) {
8753             c = *p;
8754             if (c == '\0')
8755                 break;
8756             if (c == '\\') {
8757                 p++;
8758                 /* escape */
8759                 c = *p;
8760                 switch(c) {
8761                 case '0': case '1': case '2': case '3':
8762                 case '4': case '5': case '6': case '7':
8763                     /* at most three octal digits */
8764                     n = c - '0';
8765                     p++;
8766                     c = *p;
8767                     if (isoct(c)) {
8768                         n = n * 8 + c - '0';
8769                         p++;
8770                         c = *p;
8771                         if (isoct(c)) {
8772                             n = n * 8 + c - '0';
8773                             p++;
8774                         }
8775                     }
8776                     c = n;
8777                     goto add_char_nonext;
8778                 case 'x':
8779                     p++;
8780                     n = 0;
8781                     for(;;) {
8782                         c = *p;
8783                         if (c >= 'a' && c <= 'f')
8784                             c = c - 'a' + 10;
8785                         else if (c >= 'A' && c <= 'F')
8786                             c = c - 'A' + 10;
8787                         else if (isnum(c))
8788                             c = c - '0';
8789                         else
8790                             break;
8791                         n = n * 16 + c;
8792                         p++;
8793                     }
8794                     c = n;
8795                     goto add_char_nonext;
8796                 case 'a':
8797                     c = '\a';
8798                     break;
8799                 case 'b':
8800                     c = '\b';
8801                     break;
8802                 case 'f':
8803                     c = '\f';
8804                     break;
8805                 case 'n':
8806                     c = '\n';
8807                     break;
8808                 case 'r':
8809                     c = '\r';
8810                     break;
8811                 case 't':
8812                     c = '\t';
8813                     break;
8814                 case 'v':
8815                     c = '\v';
8816                     break;
8817                 case 'e':
8818                     if (!gnu_ext)
8819                         goto invalid_escape;
8820                     c = 27;
8821                     break;
8822                 case '\'':
8823                 case '\"':
8824                 case '\\': 
8825                 case '?':
8826                     break;
8827                 default:
8828                 invalid_escape:
8829                     if (c >= '!' && c <= '~')
8830                         warning("unknown escape sequence: \'\\%c\'", c);
8831                     else
8832                         warning("unknown escape sequence: \'\\x%x\'", c);
8833                     break;
8834                 }
8835             }
8836             p++;
8837         add_char_nonext:
8838             if (!is_long)
8839                 cstr_ccat(outstr, c);
8840             else
8841                 cstr_wccat(outstr, c);
8842         }
8843         /* add a trailing '\0' */
8844         if (!is_long)
8845             cstr_ccat(outstr, '\0');
8846         else
8847             cstr_wccat(outstr, '\0');
8848     }
8849     
8850     /* we use 64 bit numbers */
8851     #define BN_SIZE 2
8852     
8853     /* bn = (bn << shift) | or_val */
8854     void bn_lshift(unsigned int *bn, int shift, int or_val)
8855     {
8856         int i;
8857         unsigned int v;
8858         for(i=0;i<BN_SIZE;i++) {
8859             v = bn[i];
8860             bn[i] = (v << shift) | or_val;
8861             or_val = v >> (32 - shift);
8862         }
8863     }
8864     
8865     void bn_zero(unsigned int *bn)
8866     {
8867         int i;
8868         for(i=0;i<BN_SIZE;i++) {
8869             bn[i] = 0;
8870         }
8871     }
8872     
8873     /* parse number in null terminated string 'p' and return it in the
8874        current token */
8875     void parse_number(const char *p)
8876     {
8877         int b, t, shift, frac_bits, s, exp_val, ch;
8878         char *q;
8879         unsigned int bn[BN_SIZE];
8880         double d;
8881     
8882         /* number */
8883         q = token_buf;
8884         ch = *p++;
8885         t = ch;
8886         ch = *p++;
8887         *q++ = t;
8888         b = 10;
8889         if (t == '.') {
8890             goto float_frac_parse;
8891         } else if (t == '0') {
8892             if (ch == 'x' || ch == 'X') {
8893                 q--;
8894                 ch = *p++;
8895                 b = 16;
8896             } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
8897                 q--;
8898                 ch = *p++;
8899                 b = 2;
8900             }
8901         }
8902         /* parse all digits. cannot check octal numbers at this stage
8903            because of floating point constants */
8904         while (1) {
8905             if (ch >= 'a' && ch <= 'f')
8906                 t = ch - 'a' + 10;
8907             else if (ch >= 'A' && ch <= 'F')
8908                 t = ch - 'A' + 10;
8909             else if (isnum(ch))
8910                 t = ch - '0';
8911             else
8912                 break;
8913             if (t >= b)
8914                 break;
8915             if (q >= token_buf + STRING_MAX_SIZE) {
8916             num_too_long:
8917                 error("number too long");
8918             }
8919             *q++ = ch;
8920             ch = *p++;
8921         }
8922         if (ch == '.' ||
8923             ((ch == 'e' || ch == 'E') && b == 10) ||
8924             ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
8925             if (b != 10) {
8926                 /* NOTE: strtox should support that for hexa numbers, but
8927                    non ISOC99 libcs do not support it, so we prefer to do
8928                    it by hand */
8929                 /* hexadecimal or binary floats */
8930                 /* XXX: handle overflows */
8931                 *q = '\0';
8932                 if (b == 16)
8933                     shift = 4;
8934                 else 
8935                     shift = 2;
8936                 bn_zero(bn);
8937                 q = token_buf;
8938                 while (1) {
8939                     t = *q++;
8940                     if (t == '\0') {
8941                         break;
8942                     } else if (t >= 'a') {
8943                         t = t - 'a' + 10;
8944                     } else if (t >= 'A') {
8945                         t = t - 'A' + 10;
8946                     } else {
8947                         t = t - '0';
8948                     }
8949                     bn_lshift(bn, shift, t);
8950                 }
8951                 frac_bits = 0;
8952                 if (ch == '.') {
8953                     ch = *p++;
8954                     while (1) {
8955                         t = ch;
8956                         if (t >= 'a' && t <= 'f') {
8957                             t = t - 'a' + 10;
8958                         } else if (t >= 'A' && t <= 'F') {
8959                             t = t - 'A' + 10;
8960                         } else if (t >= '0' && t <= '9') {
8961                             t = t - '0';
8962                         } else {
8963                             break;
8964                         }
8965                         if (t >= b)
8966                             error("invalid digit");
8967                         bn_lshift(bn, shift, t);
8968                         frac_bits += shift;
8969                         ch = *p++;
8970                     }
8971                 }
8972                 if (ch != 'p' && ch != 'P')
8973                     expect("exponent");
8974                 ch = *p++;
8975                 s = 1;
8976                 exp_val = 0;
8977                 if (ch == '+') {
8978                     ch = *p++;
8979                 } else if (ch == '-') {
8980                     s = -1;
8981                     ch = *p++;
8982                 }
8983                 if (ch < '0' || ch > '9')
8984                     expect("exponent digits");
8985                 while (ch >= '0' && ch <= '9') {
8986                     exp_val = exp_val * 10 + ch - '0';
8987                     ch = *p++;
8988                 }
8989                 exp_val = exp_val * s;
8990                 
8991                 /* now we can generate the number */
8992                 /* XXX: should patch directly float number */
8993                 d = (double)bn[1] * 4294967296.0 + (double)bn[0];
8994                 d = ldexp(d, exp_val - frac_bits);
8995                 t = toup(ch);
8996                 if (t == 'F') {
8997                     ch = *p++;
8998                     tok = TOK_CFLOAT;
8999                     /* float : should handle overflow */
9000                     tokc.f = (float)d;
9001                 } else if (t == 'L') {
9002                     ch = *p++;
9003                     tok = TOK_CLDOUBLE;
9004                     /* XXX: not large enough */
9005                     tokc.ld = (long double)d;
9006                 } else {
9007                     tok = TOK_CDOUBLE;
9008                     tokc.d = d;
9009                 }
9010             } else {
9011                 /* decimal floats */
9012                 if (ch == '.') {
9013                     if (q >= token_buf + STRING_MAX_SIZE)
9014                         goto num_too_long;
9015                     *q++ = ch;
9016                     ch = *p++;
9017                 float_frac_parse:
9018                     while (ch >= '0' && ch <= '9') {
9019                         if (q >= token_buf + STRING_MAX_SIZE)
9020                             goto num_too_long;
9021                         *q++ = ch;
9022                         ch = *p++;
9023                     }
9024                 }
9025                 if (ch == 'e' || ch == 'E') {
9026                     if (q >= token_buf + STRING_MAX_SIZE)
9027                         goto num_too_long;
9028                     *q++ = ch;
9029                     ch = *p++;
9030                     if (ch == '-' || ch == '+') {
9031                         if (q >= token_buf + STRING_MAX_SIZE)
9032                             goto num_too_long;
9033                         *q++ = ch;
9034                         ch = *p++;
9035                     }
9036                     if (ch < '0' || ch > '9')
9037                         expect("exponent digits");
9038                     while (ch >= '0' && ch <= '9') {
9039                         if (q >= token_buf + STRING_MAX_SIZE)
9040                             goto num_too_long;
9041                         *q++ = ch;
9042                         ch = *p++;
9043                     }
9044                 }
9045                 *q = '\0';
9046                 t = toup(ch);
9047                 errno = 0;
9048                 if (t == 'F') {
9049                     ch = *p++;
9050                     tok = TOK_CFLOAT;
9051                     tokc.f = strtof(token_buf, NULL);
9052                 } else if (t == 'L') {
9053                     ch = *p++;
9054                     tok = TOK_CLDOUBLE;
9055                     tokc.ld = strtold(token_buf, NULL);
9056                 } else {
9057                     tok = TOK_CDOUBLE;
9058                     tokc.d = strtod(token_buf, NULL);
9059                 }
9060             }
9061         } else {
9062             unsigned long long n, n1;
9063             int lcount, ucount;
9064     
9065             /* integer number */
9066             *q = '\0';
9067             q = token_buf;
9068             if (b == 10 && *q == '0') {
9069                 b = 8;
9070                 q++;
9071             }
9072             n = 0;
9073             while(1) {
9074                 t = *q++;
9075                 /* no need for checks except for base 10 / 8 errors */
9076                 if (t == '\0') {
9077                     break;
9078                 } else if (t >= 'a') {
9079                     t = t - 'a' + 10;
9080                 } else if (t >= 'A') {
9081                     t = t - 'A' + 10;
9082                 } else {
9083                     t = t - '0';
9084                     if (t >= b)
9085                         error("invalid digit");
9086                 }
9087                 n1 = n;
9088                 n = n * b + t;
9089                 /* detect overflow */
9090                 /* XXX: this test is not reliable */
9091                 if (n < n1)
9092                     error("integer constant overflow");
9093             }
9094             
9095             /* XXX: not exactly ANSI compliant */
9096             if ((n & 0xffffffff00000000LL) != 0) {
9097                 if ((n >> 63) != 0)
9098                     tok = TOK_CULLONG;
9099                 else
9100                     tok = TOK_CLLONG;
9101             } else if (n > 0x7fffffff) {
9102                 tok = TOK_CUINT;
9103             } else {
9104                 tok = TOK_CINT;
9105             }
9106             lcount = 0;
9107             ucount = 0;
9108             for(;;) {
9109                 t = toup(ch);
9110                 if (t == 'L') {
9111                     if (lcount >= 2)
9112                         error("three 'l's in integer constant");
9113                     lcount++;
9114                     if (lcount == 2) {
9115                         if (tok == TOK_CINT)
9116                             tok = TOK_CLLONG;
9117                         else if (tok == TOK_CUINT)
9118                             tok = TOK_CULLONG;
9119                     }
9120                     ch = *p++;
9121                 } else if (t == 'U') {
9122                     if (ucount >= 1)
9123                         error("two 'u's in integer constant");
9124                     ucount++;
9125                     if (tok == TOK_CINT)
9126                         tok = TOK_CUINT;
9127                     else if (tok == TOK_CLLONG)
9128                         tok = TOK_CULLONG;
9129                     ch = *p++;
9130                 } else {
9131                     break;
9132                 }
9133             }
9134             if (tok == TOK_CINT || tok == TOK_CUINT)
9135                 tokc.ui = n;
9136             else
9137                 tokc.ull = n;
9138         }
9139     }
9140     
9141     
9142     #define PARSE2(c1, tok1, c2, tok2)              \
9143         case c1:                                    \
9144             PEEKC(c, p);                            \
9145             if (c == c2) {                          \
9146                 p++;                                \
9147                 tok = tok2;                         \
9148             } else {                                \
9149                 tok = tok1;                         \
9150             }                                       \
9151             break;
9152     
9153     /* return next token without macro substitution */
9154     static /*inline*/ void next_nomacro1(void)
9155     {
9156         int t, c, is_long;
9157         TokenSym *ts;
9158         uint8_t *p, *p1;
9159         unsigned int h;
9160     
9161         p = file->buf_ptr;
9162      redo_no_start:
9163         c = *p;
9164         switch(c) {
9165         case ' ':
9166         case '\t':
9167         case '\f':
9168         case '\v':
9169         case '\r':
9170             p++;
9171             goto redo_no_start;
9172             
9173         case '\\':
9174             /* first look if it is in fact an end of buffer */
9175             if (p >= file->buf_end) {
9176                 file->buf_ptr = p;
9177                 handle_eob();
9178                 p = file->buf_ptr;
9179                 if (p >= file->buf_end)
9180                     goto parse_eof;
9181                 else
9182                     goto redo_no_start;
9183             } else {
9184                 file->buf_ptr = p;
9185                 ch = *p;
9186                 handle_stray();
9187                 p = file->buf_ptr;
9188                 goto redo_no_start;
9189             }
9190         parse_eof:
9191             {
9192                 TCCState *s1 = tcc_state;
9193                 if (parse_flags & PARSE_FLAG_LINEFEED) {
9194                     tok = TOK_LINEFEED;
9195                 } else if (s1->include_stack_ptr == s1->include_stack ||
9196                            !(parse_flags & PARSE_FLAG_PREPROCESS)) {
9197                     /* no include left : end of file. */
9198                     tok = TOK_EOF;
9199                 } else {
9200                     /* pop include file */
9201                     
9202                     /* test if previous '#endif' was after a #ifdef at
9203                        start of file */
9204                     if (tok_flags & TOK_FLAG_ENDIF) {
9205     #ifdef INC_DEBUG
9206                         printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL));
9207     #endif
9208                         add_cached_include(s1, file->inc_type, file->inc_filename,
9209                                            file->ifndef_macro_saved);
9210                     }
9211     
9212                     /* add end of include file debug info */
9213                     if (do_debug) {
9214                         put_stabd(N_EINCL, 0, 0);
9215                     }
9216                     /* pop include stack */
9217                     tcc_close(file);
9218                     s1->include_stack_ptr--;
9219                     file = *s1->include_stack_ptr;
9220                     p = file->buf_ptr;
9221                     goto redo_no_start;
9222                 }
9223             }
9224             break;
9225     
9226         case '\n':
9227             if (parse_flags & PARSE_FLAG_LINEFEED) {
9228                 tok = TOK_LINEFEED;
9229             } else {
9230                 file->line_num++;
9231                 tok_flags |= TOK_FLAG_BOL;
9232                 p++;
9233                 goto redo_no_start;
9234             }
9235             break;
9236     
9237         case '#':
9238             /* XXX: simplify */
9239             PEEKC(c, p);
9240             if ((tok_flags & TOK_FLAG_BOL) && 
9241                 (parse_flags & PARSE_FLAG_PREPROCESS)) {
9242                 file->buf_ptr = p;
9243                 preprocess(tok_flags & TOK_FLAG_BOF);
9244                 p = file->buf_ptr;
9245                 goto redo_no_start;
9246             } else {
9247                 if (c == '#') {
9248                     p++;
9249                     tok = TOK_TWOSHARPS;
9250                 } else {
9251                     if (parse_flags & PARSE_FLAG_ASM_COMMENTS) {
9252                         p = parse_line_comment(p - 1);
9253                         goto redo_no_start;
9254                     } else {
9255                         tok = '#';
9256                     }
9257                 }
9258             }
9259             break;
9260     
9261         case 'a': case 'b': case 'c': case 'd':
9262         case 'e': case 'f': case 'g': case 'h':
9263         case 'i': case 'j': case 'k': case 'l':
9264         case 'm': case 'n': case 'o': case 'p':
9265         case 'q': case 'r': case 's': case 't':
9266         case 'u': case 'v': case 'w': case 'x':
9267         case 'y': case 'z': 
9268         case 'A': case 'B': case 'C': case 'D':
9269         case 'E': case 'F': case 'G': case 'H':
9270         case 'I': case 'J': case 'K': 
9271         case 'M': case 'N': case 'O': case 'P':
9272         case 'Q': case 'R': case 'S': case 'T':
9273         case 'U': case 'V': case 'W': case 'X':
9274         case 'Y': case 'Z': 
9275         case '_':
9276         parse_ident_fast:
9277             p1 = p;
9278             h = TOK_HASH_INIT;
9279             h = TOK_HASH_FUNC(h, c);
9280             p++;
9281             for(;;) {
9282                 c = *p;
9283                 if (!isidnum_table[c])
9284                     break;
9285                 h = TOK_HASH_FUNC(h, c);
9286                 p++;
9287             }
9288             if (c != '\\') {
9289                 TokenSym **pts;
9290                 int len;
9291     
9292                 /* fast case : no stray found, so we have the full token
9293                    and we have already hashed it */
9294                 len = p - p1;
9295                 h &= (TOK_HASH_SIZE - 1);
9296                 pts = &hash_ident[h];
9297                 for(;;) {
9298                     ts = *pts;
9299                     if (!ts)
9300                         break;
9301                     if (ts->len == len && !memcmp(ts->str, p1, len))
9302                         goto token_found;
9303                     pts = &(ts->hash_next);
9304                 }
9305                 ts = tok_alloc_new(pts, p1, len);
9306             token_found: ;
9307             } else {
9308                 /* slower case */
9309                 cstr_reset(&tokcstr);
9310     
9311                 while (p1 < p) {
9312                     cstr_ccat(&tokcstr, *p1);
9313                     p1++;
9314                 }
9315                 p--;
9316                 PEEKC(c, p);
9317             parse_ident_slow:
9318                 while (isidnum_table[c]) {
9319                     cstr_ccat(&tokcstr, c);
9320                     PEEKC(c, p);
9321                 }
9322                 ts = tok_alloc(tokcstr.data, tokcstr.size);
9323             }
9324             tok = ts->tok;
9325             break;
9326         case 'L':
9327             t = p[1];
9328             if (t != '\\' && t != '\'' && t != '\"') {
9329                 /* fast case */
9330                 goto parse_ident_fast;
9331             } else {
9332                 PEEKC(c, p);
9333                 if (c == '\'' || c == '\"') {
9334                     is_long = 1;
9335                     goto str_const;
9336                 } else {
9337                     cstr_reset(&tokcstr);
9338                     cstr_ccat(&tokcstr, 'L');
9339                     goto parse_ident_slow;
9340                 }
9341             }
9342             break;
9343         case '0': case '1': case '2': case '3':
9344         case '4': case '5': case '6': case '7':
9345         case '8': case '9':
9346     
9347             cstr_reset(&tokcstr);
9348             /* after the first digit, accept digits, alpha, '.' or sign if
9349                prefixed by 'eEpP' */
9350         parse_num:
9351             for(;;) {
9352                 t = c;
9353                 cstr_ccat(&tokcstr, c);
9354                 PEEKC(c, p);
9355                 if (!(isnum(c) || isid(c) || c == '.' ||
9356                       ((c == '+' || c == '-') && 
9357                        (t == 'e' || t == 'E' || t == 'p' || t == 'P'))))
9358                     break;
9359             }
9360             /* We add a trailing '\0' to ease parsing */
9361             cstr_ccat(&tokcstr, '\0');
9362             tokc.cstr = &tokcstr;
9363             tok = TOK_PPNUM;
9364             break;
9365         case '.':
9366             /* special dot handling because it can also start a number */
9367             PEEKC(c, p);
9368             if (isnum(c)) {
9369                 cstr_reset(&tokcstr);
9370                 cstr_ccat(&tokcstr, '.');
9371                 goto parse_num;
9372             } else if (c == '.') {
9373                 PEEKC(c, p);
9374                 if (c != '.')
9375                     expect("'.'");
9376                 PEEKC(c, p);
9377                 tok = TOK_DOTS;
9378             } else {
9379                 tok = '.';
9380             }
9381             break;
9382         case '\'':
9383         case '\"':
9384             is_long = 0;
9385         str_const:
9386             {
9387                 CString str;
9388                 int sep;
9389     
9390                 sep = c;
9391     
9392                 /* parse the string */
9393                 cstr_new(&str);
9394                 p = parse_pp_string(p, sep, &str);
9395                 cstr_ccat(&str, '\0');
9396                 
9397                 /* eval the escape (should be done as TOK_PPNUM) */
9398                 cstr_reset(&tokcstr);
9399                 parse_escape_string(&tokcstr, str.data, is_long);
9400                 cstr_free(&str);
9401     
9402                 if (sep == '\'') {
9403                     int char_size;
9404                     /* XXX: make it portable */
9405                     if (!is_long)
9406                         char_size = 1;
9407                     else
9408                         char_size = sizeof(int);
9409                     if (tokcstr.size <= char_size)
9410                         error("empty character constant");
9411                     if (tokcstr.size > 2 * char_size)
9412                         warning("multi-character character constant");
9413                     if (!is_long) {
9414                         tokc.i = *(int8_t *)tokcstr.data;
9415                         tok = TOK_CCHAR;
9416                     } else {
9417                         tokc.i = *(int *)tokcstr.data;
9418                         tok = TOK_LCHAR;
9419                     }
9420                 } else {
9421                     tokc.cstr = &tokcstr;
9422                     if (!is_long)
9423                         tok = TOK_STR;
9424                     else
9425                         tok = TOK_LSTR;
9426                 }
9427             }
9428             break;
9429     
9430         case '<':
9431             PEEKC(c, p);
9432             if (c == '=') {
9433                 p++;
9434                 tok = TOK_LE;
9435             } else if (c == '<') {
9436                 PEEKC(c, p);
9437                 if (c == '=') {
9438                     p++;
9439                     tok = TOK_A_SHL;
9440                 } else {
9441                     tok = TOK_SHL;
9442                 }
9443             } else {
9444                 tok = TOK_LT;
9445             }
9446             break;
9447             
9448         case '>':
9449             PEEKC(c, p);
9450             if (c == '=') {
9451                 p++;
9452                 tok = TOK_GE;
9453             } else if (c == '>') {
9454                 PEEKC(c, p);
9455                 if (c == '=') {
9456                     p++;
9457                     tok = TOK_A_SAR;
9458                 } else {
9459                     tok = TOK_SAR;
9460                 }
9461             } else {
9462                 tok = TOK_GT;
9463             }
9464             break;
9465             
9466         case '&':
9467             PEEKC(c, p);
9468             if (c == '&') {
9469                 p++;
9470                 tok = TOK_LAND;
9471             } else if (c == '=') {
9472                 p++;
9473                 tok = TOK_A_AND;
9474             } else {
9475                 tok = '&';
9476             }
9477             break;
9478             
9479         case '|':
9480             PEEKC(c, p);
9481             if (c == '|') {
9482                 p++;
9483                 tok = TOK_LOR;
9484             } else if (c == '=') {
9485                 p++;
9486                 tok = TOK_A_OR;
9487             } else {
9488                 tok = '|';
9489             }
9490             break;
9491     
9492         case '+':
9493             PEEKC(c, p);
9494             if (c == '+') {
9495                 p++;
9496                 tok = TOK_INC;
9497             } else if (c == '=') {
9498                 p++;
9499                 tok = TOK_A_ADD;
9500             } else {
9501                 tok = '+';
9502             }
9503             break;
9504             
9505         case '-':
9506             PEEKC(c, p);
9507             if (c == '-') {
9508                 p++;
9509                 tok = TOK_DEC;
9510             } else if (c == '=') {
9511                 p++;
9512                 tok = TOK_A_SUB;
9513             } else if (c == '>') {
9514                 p++;
9515                 tok = TOK_ARROW;
9516             } else {
9517                 tok = '-';
9518             }
9519             break;
9520     
9521         PARSE2('!', '!', '=', TOK_NE)
9522         PARSE2('=', '=', '=', TOK_EQ)
9523         PARSE2('*', '*', '=', TOK_A_MUL)
9524         PARSE2('%', '%', '=', TOK_A_MOD)
9525         PARSE2('^', '^', '=', TOK_A_XOR)
9526             
9527             /* comments or operator */
9528         case '/':
9529             PEEKC(c, p);
9530             if (c == '*') {
9531                 p = parse_comment(p);
9532                 goto redo_no_start;
9533             } else if (c == '/') {
9534                 p = parse_line_comment(p);
9535                 goto redo_no_start;
9536             } else if (c == '=') {
9537                 p++;
9538                 tok = TOK_A_DIV;
9539             } else {
9540                 tok = '/';
9541             }
9542             break;
9543             
9544             /* simple tokens */
9545         case '(':
9546         case ')':
9547         case '[':
9548         case ']':
9549         case '{':
9550         case '}':
9551         case ',':
9552         case ';':
9553         case ':':
9554         case '?':
9555         case '~':
9556         case '$': /* only used in assembler */
9557         case '@': /* dito */
9558             tok = c;
9559             p++;
9560             break;
9561         default:
9562             error("unrecognized character \\x%02x", c);
9563             break;
9564         }
9565         file->buf_ptr = p;
9566         tok_flags = 0;
9567     #if defined(PARSE_DEBUG)
9568         printf("token = %s\n", get_tok_str(tok, &tokc));
9569     #endif
9570     }
9571     
9572     /* return next token without macro substitution. Can read input from
9573        macro_ptr buffer */
9574     static void next_nomacro(void)
9575     {
9576         if (macro_ptr) {
9577         redo:
9578             tok = *macro_ptr;
9579             if (tok) {
9580                 TOK_GET(tok, macro_ptr, tokc);
9581                 if (tok == TOK_LINENUM) {
9582                     file->line_num = tokc.i;
9583                     goto redo;
9584                 }
9585             }
9586         } else {
9587             next_nomacro1();
9588         }
9589     }
9590     
9591     /* substitute args in macro_str and return allocated string */
9592     static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
9593     {
9594         int *st, last_tok, t, notfirst;
9595         Sym *s;
9596         CValue cval;
9597         TokenString str;
9598         CString cstr;
9599     
9600         tok_str_new(&str);
9601         last_tok = 0;
9602         while(1) {
9603             TOK_GET(t, macro_str, cval);
9604             if (!t)
9605                 break;
9606             if (t == '#') {
9607                 /* stringize */
9608                 TOK_GET(t, macro_str, cval);
9609                 if (!t)
9610                     break;
9611                 s = sym_find2(args, t);
9612                 if (s) {
9613                     cstr_new(&cstr);
9614                     st = (int *)s->c;
9615                     notfirst = 0;
9616                     while (*st) {
9617                         if (notfirst)
9618                             cstr_ccat(&cstr, ' ');
9619                         TOK_GET(t, st, cval);
9620                         cstr_cat(&cstr, get_tok_str(t, &cval));
9621                         notfirst = 1;
9622                     }
9623                     cstr_ccat(&cstr, '\0');
9624     #ifdef PP_DEBUG
9625                     printf("stringize: %s\n", (char *)cstr.data);
9626     #endif
9627                     /* add string */
9628                     cval.cstr = &cstr;
9629                     tok_str_add2(&str, TOK_STR, &cval);
9630                     cstr_free(&cstr);
9631                 } else {
9632                     tok_str_add2(&str, t, &cval);
9633                 }
9634             } else if (t >= TOK_IDENT) {
9635                 s = sym_find2(args, t);
9636                 if (s) {
9637                     st = (int *)s->c;
9638                     /* if '##' is present before or after, no arg substitution */
9639                     if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
9640                         /* special case for var arg macros : ## eats the
9641                            ',' if empty VA_ARGS variable. */
9642                         /* XXX: test of the ',' is not 100%
9643                            reliable. should fix it to avoid security
9644                            problems */
9645                         if (gnu_ext && s->type.t &&
9646                             last_tok == TOK_TWOSHARPS && 
9647                             str.len >= 2 && str.str[str.len - 2] == ',') {
9648                             if (*st == 0) {
9649                                 /* suppress ',' '##' */
9650                                 str.len -= 2;
9651                             } else {
9652                                 /* suppress '##' and add variable */
9653                                 str.len--;
9654                                 goto add_var;
9655                             }
9656                         } else {
9657                             int t1;
9658                         add_var:
9659                             for(;;) {
9660                                 TOK_GET(t1, st, cval);
9661                                 if (!t1)
9662                                     break;
9663                                 tok_str_add2(&str, t1, &cval);
9664                             }
9665                         }
9666                     } else {
9667                         /* NOTE: the stream cannot be read when macro
9668                            substituing an argument */
9669                         macro_subst(&str, nested_list, st, NULL);
9670                     }
9671                 } else {
9672                     tok_str_add(&str, t);
9673                 }
9674             } else {
9675                 tok_str_add2(&str, t, &cval);
9676             }
9677             last_tok = t;
9678         }
9679         tok_str_add(&str, 0);
9680         return str.str;
9681     }
9682     
9683     static char const ab_month_name[12][4] =
9684     {
9685         "Jan", "Feb", "Mar", "Apr", "May", "Jun",
9686         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
9687     };
9688     
9689     /* do macro substitution of current token with macro 's' and add
9690        result to (tok_str,tok_len). 'nested_list' is the list of all
9691        macros we got inside to avoid recursing. Return non zero if no
9692        substitution needs to be done */
9693     static int macro_subst_tok(TokenString *tok_str,
9694                                Sym **nested_list, Sym *s, struct macro_level **can_read_stream)
9695     {
9696         Sym *args, *sa, *sa1;
9697         int mstr_allocated, parlevel, *mstr, t, t1;
9698         TokenString str;
9699         char *cstrval;
9700         CValue cval;
9701         CString cstr;
9702         char buf[32];
9703         
9704         /* if symbol is a macro, prepare substitution */
9705         /* special macros */
9706         if (tok == TOK___LINE__) {
9707             snprintf(buf, sizeof(buf), "%d", file->line_num);
9708             cstrval = buf;
9709             t1 = TOK_PPNUM;
9710             goto add_cstr1;
9711         } else if (tok == TOK___FILE__) {
9712             cstrval = file->filename;
9713             goto add_cstr;
9714         } else if (tok == TOK___DATE__ || tok == TOK___TIME__) {
9715             time_t ti;
9716             struct tm *tm;
9717     
9718             time(&ti);
9719             tm = localtime(&ti);
9720             if (tok == TOK___DATE__) {
9721                 snprintf(buf, sizeof(buf), "%s %2d %d", 
9722                          ab_month_name[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900);
9723             } else {
9724                 snprintf(buf, sizeof(buf), "%02d:%02d:%02d", 
9725                          tm->tm_hour, tm->tm_min, tm->tm_sec);
9726             }
9727             cstrval = buf;
9728         add_cstr:
9729             t1 = TOK_STR;
9730         add_cstr1:
9731             cstr_new(&cstr);
9732             cstr_cat(&cstr, cstrval);
9733             cstr_ccat(&cstr, '\0');
9734             cval.cstr = &cstr;
9735             tok_str_add2(tok_str, t1, &cval);
9736             cstr_free(&cstr);
9737         } else {
9738             mstr = (int *)s->c;
9739             mstr_allocated = 0;
9740             if (s->type.t == MACRO_FUNC) {
9741                 /* NOTE: we do not use next_nomacro to avoid eating the
9742                    next token. XXX: find better solution */
9743             redo:
9744                 if (macro_ptr) {
9745                     t = *macro_ptr;
9746                     if (t == 0 && can_read_stream) {
9747                         /* end of macro stream: we must look at the token
9748                            after in the file */
9749                         struct macro_level *ml = *can_read_stream;
9750                         macro_ptr = NULL;
9751                         if (ml)
9752                         {
9753                             macro_ptr = ml->p;
9754                             ml->p = NULL;
9755                             *can_read_stream = ml -> prev;
9756                         }
9757                         goto redo;
9758                     }
9759                 } else {
9760                     /* XXX: incorrect with comments */
9761                     ch = file->buf_ptr[0];
9762                     while (is_space(ch) || ch == '\n')
9763                         cinp();
9764                     t = ch;
9765                 }
9766                 if (t != '(') /* no macro subst */
9767                     return -1;
9768                         
9769                 /* argument macro */
9770                 next_nomacro();
9771                 next_nomacro();
9772                 args = NULL;
9773                 sa = s->next;
9774                 /* NOTE: empty args are allowed, except if no args */
9775                 for(;;) {
9776                     /* handle '()' case */
9777                     if (!args && !sa && tok == ')')
9778                         break;
9779                     if (!sa)
9780                         error("macro '%s' used with too many args",
9781                               get_tok_str(s->v, 0));
9782                     tok_str_new(&str);
9783                     parlevel = 0;
9784                     /* NOTE: non zero sa->t indicates VA_ARGS */
9785                     while ((parlevel > 0 || 
9786                             (tok != ')' && 
9787                              (tok != ',' || sa->type.t))) && 
9788                            tok != -1) {
9789                         if (tok == '(')
9790                             parlevel++;
9791                         else if (tok == ')')
9792                             parlevel--;
9793                         tok_str_add2(&str, tok, &tokc);
9794                         next_nomacro();
9795                     }
9796                     tok_str_add(&str, 0);
9797                     sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, (long)str.str);
9798                     sa = sa->next;
9799                     if (tok == ')') {
9800                         /* special case for gcc var args: add an empty
9801                            var arg argument if it is omitted */
9802                         if (sa && sa->type.t && gnu_ext)
9803                             continue;
9804                         else
9805                             break;
9806                     }
9807                     if (tok != ',')
9808                         expect(",");
9809                     next_nomacro();
9810                 }
9811                 if (sa) {
9812                     error("macro '%s' used with too few args",
9813                           get_tok_str(s->v, 0));
9814                 }
9815     
9816                 /* now subst each arg */
9817                 mstr = macro_arg_subst(nested_list, mstr, args);
9818                 /* free memory */
9819                 sa = args;
9820                 while (sa) {
9821                     sa1 = sa->prev;
9822                     tok_str_free((int *)sa->c);
9823                     sym_free(sa);
9824                     sa = sa1;
9825                 }
9826                 mstr_allocated = 1;
9827             }
9828             sym_push2(nested_list, s->v, 0, 0);
9829             macro_subst(tok_str, nested_list, mstr, can_read_stream);
9830             /* pop nested defined symbol */
9831             sa1 = *nested_list;
9832             *nested_list = sa1->prev;
9833             sym_free(sa1);
9834             if (mstr_allocated)
9835                 tok_str_free(mstr);
9836         }
9837         return 0;
9838     }
9839     
9840     /* handle the '##' operator. Return NULL if no '##' seen. Otherwise
9841        return the resulting string (which must be freed). */
9842     static /*inline*/ int *macro_twosharps(const int *macro_str)
9843     {
9844         TokenSym *ts;
9845         const int *macro_ptr1, *start_macro_ptr, *ptr, *saved_macro_ptr;
9846         int t;
9847         const char *p1, *p2;
9848         CValue cval;
9849         TokenString macro_str1;
9850         CString cstr;
9851     
9852         start_macro_ptr = macro_str;
9853         /* we search the first '##' */
9854         for(;;) {
9855             macro_ptr1 = macro_str;
9856             TOK_GET(t, macro_str, cval);
9857             /* nothing more to do if end of string */
9858             if (t == 0)
9859                 return NULL;
9860             if (*macro_str == TOK_TWOSHARPS)
9861                 break;
9862         }
9863     
9864         /* we saw '##', so we need more processing to handle it */
9865         cstr_new(&cstr);
9866         tok_str_new(&macro_str1);
9867         tok = t;
9868         tokc = cval;
9869     
9870         /* add all tokens seen so far */
9871         for(ptr = start_macro_ptr; ptr < macro_ptr1;) {
9872             TOK_GET(t, ptr, cval);
9873             tok_str_add2(&macro_str1, t, &cval);
9874         }
9875         saved_macro_ptr = macro_ptr;
9876         /* XXX: get rid of the use of macro_ptr here */
9877         macro_ptr = (int *)macro_str;
9878         for(;;) {
9879             while (*macro_ptr == TOK_TWOSHARPS) {
9880                 macro_ptr++;
9881                 macro_ptr1 = macro_ptr;
9882                 t = *macro_ptr;
9883                 if (t) {
9884                     TOK_GET(t, macro_ptr, cval);
9885                     /* We concatenate the two tokens if we have an
9886                        identifier or a preprocessing number */
9887                     cstr_reset(&cstr);
9888                     p1 = get_tok_str(tok, &tokc);
9889                     cstr_cat(&cstr, p1);
9890                     p2 = get_tok_str(t, &cval);
9891                     cstr_cat(&cstr, p2);
9892                     cstr_ccat(&cstr, '\0');
9893                     
9894                     if ((tok >= TOK_IDENT || tok == TOK_PPNUM) && 
9895                         (t >= TOK_IDENT || t == TOK_PPNUM)) {
9896                         if (tok == TOK_PPNUM) {
9897                             /* if number, then create a number token */
9898                             /* NOTE: no need to allocate because
9899                                tok_str_add2() does it */
9900                             tokc.cstr = &cstr;
9901                         } else {
9902                             /* if identifier, we must do a test to
9903                                validate we have a correct identifier */
9904                             if (t == TOK_PPNUM) {
9905                                 const char *p;
9906                                 int c;
9907     
9908                                 p = p2;
9909                                 for(;;) {
9910                                     c = *p;
9911                                     if (c == '\0')
9912                                         break;
9913                                     p++;
9914                                     if (!isnum(c) && !isid(c))
9915                                         goto error_pasting;
9916                                 }
9917                             }
9918                             ts = tok_alloc(cstr.data, strlen(cstr.data));
9919                             tok = ts->tok; /* modify current token */
9920                         }
9921                     } else {
9922                         const char *str = cstr.data;
9923                         const unsigned char *q;
9924     
9925                         /* we look for a valid token */
9926                         /* XXX: do more extensive checks */
9927                         if (!strcmp(str, ">>=")) {
9928                             tok = TOK_A_SAR;
9929                         } else if (!strcmp(str, "<<=")) {
9930                             tok = TOK_A_SHL;
9931                         } else if (strlen(str) == 2) {
9932                             /* search in two bytes table */
9933                             q = tok_two_chars;
9934                             for(;;) {
9935                                 if (!*q)
9936                                     goto error_pasting;
9937                                 if (q[0] == str[0] && q[1] == str[1])
9938                                     break;
9939                                 q += 3;
9940                             }
9941                             tok = q[2];
9942                         } else {
9943                         error_pasting:
9944                             /* NOTE: because get_tok_str use a static buffer,
9945                                we must save it */
9946                             cstr_reset(&cstr);
9947                             p1 = get_tok_str(tok, &tokc);
9948                             cstr_cat(&cstr, p1);
9949                             cstr_ccat(&cstr, '\0');
9950                             p2 = get_tok_str(t, &cval);
9951                             warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2);
9952                             /* cannot merge tokens: just add them separately */
9953                             tok_str_add2(&macro_str1, tok, &tokc);
9954                             /* XXX: free associated memory ? */
9955                             tok = t;
9956                             tokc = cval;
9957                         }
9958                     }
9959                 }
9960             }
9961             tok_str_add2(&macro_str1, tok, &tokc);
9962             next_nomacro();
9963             if (tok == 0)
9964                 break;
9965         }
9966         macro_ptr = (int *)saved_macro_ptr;
9967         cstr_free(&cstr);
9968         tok_str_add(&macro_str1, 0);
9969         return macro_str1.str;
9970     }
9971     
9972     
9973     /* do macro substitution of macro_str and add result to
9974        (tok_str,tok_len). 'nested_list' is the list of all macros we got
9975        inside to avoid recursing. */
9976     static void macro_subst(TokenString *tok_str, Sym **nested_list, 
9977                             const int *macro_str, struct macro_level ** can_read_stream)
9978     {
9979         Sym *s;
9980         int *macro_str1;
9981         const int *ptr;
9982         int t, ret;
9983         CValue cval;
9984         struct macro_level ml;
9985         
9986         /* first scan for '##' operator handling */
9987         ptr = macro_str;
9988         macro_str1 = macro_twosharps(ptr);
9989         if (macro_str1) 
9990             ptr = macro_str1;
9991         while (1) {
9992             /* NOTE: ptr == NULL can only happen if tokens are read from
9993                file stream due to a macro function call */
9994             if (ptr == NULL)
9995                 break;
9996             TOK_GET(t, ptr, cval);
9997             if (t == 0)
9998                 break;
9999             s = define_find(t);
10000             if (s != NULL) {
10001                 /* if nested substitution, do nothing */
10002                 if (sym_find2(*nested_list, t))
10003                     goto no_subst;
10004                 ml.p = macro_ptr;
10005                 if (can_read_stream)
10006                     ml.prev = *can_read_stream, *can_read_stream = &ml;
10007                 macro_ptr = (int *)ptr;
10008                 tok = t;
10009                 ret = macro_subst_tok(tok_str, nested_list, s, can_read_stream);
10010                 ptr = (int *)macro_ptr;
10011                 macro_ptr = ml.p;
10012                 if (can_read_stream && *can_read_stream == &ml)
10013                         *can_read_stream = ml.prev;
10014                 if (ret != 0)
10015                     goto no_subst;
10016             } else {
10017             no_subst:
10018                 tok_str_add2(tok_str, t, &cval);
10019             }
10020         }
10021         if (macro_str1)
10022             tok_str_free(macro_str1);
10023     }
10024     
10025     /* return next token with macro substitution */
10026     static void next(void)
10027     {
10028         Sym *nested_list, *s;
10029         TokenString str;
10030         struct macro_level *ml;
10031     
10032      redo:
10033         next_nomacro();
10034         if (!macro_ptr) {
10035             /* if not reading from macro substituted string, then try
10036                to substitute macros */
10037             if (tok >= TOK_IDENT &&
10038                 (parse_flags & PARSE_FLAG_PREPROCESS)) {
10039                 s = define_find(tok);
10040                 if (s) {
10041                     /* we have a macro: we try to substitute */
10042                     tok_str_new(&str);
10043                     nested_list = NULL;
10044                     ml = NULL;
10045                     if (macro_subst_tok(&str, &nested_list, s, &ml) == 0) {
10046                         /* substitution done, NOTE: maybe empty */
10047                         tok_str_add(&str, 0);
10048                         macro_ptr = str.str;
10049                         macro_ptr_allocated = str.str;
10050                         goto redo;
10051                     }
10052                 }
10053             }
10054         } else {
10055             if (tok == 0) {
10056                 /* end of macro or end of unget buffer */
10057                 if (unget_buffer_enabled) {
10058                     macro_ptr = unget_saved_macro_ptr;
10059                     unget_buffer_enabled = 0;
10060                 } else {
10061                     /* end of macro string: free it */
10062                     tok_str_free(macro_ptr_allocated);
10063                     macro_ptr = NULL;
10064                 }
10065                 goto redo;
10066             }
10067         }
10068         
10069         /* convert preprocessor tokens into C tokens */
10070         if (tok == TOK_PPNUM &&
10071             (parse_flags & PARSE_FLAG_TOK_NUM)) {
10072             parse_number((char *)tokc.cstr->data);
10073         }
10074     }
10075     
10076     /* push back current token and set current token to 'last_tok'. Only
10077        identifier case handled for labels. */
10078     static inline void unget_tok(int last_tok)
10079     {
10080         int i, n;
10081         int *q;
10082         unget_saved_macro_ptr = macro_ptr;
10083         unget_buffer_enabled = 1;
10084         q = unget_saved_buffer;
10085         macro_ptr = q;
10086         *q++ = tok;
10087         n = tok_ext_size(tok) - 1;
10088         for(i=0;i<n;i++)
10089             *q++ = tokc.tab[i];
10090         *q = 0; /* end of token string */
10091         tok = last_tok;
10092     }
10093     
10094     
10095     void swap(int *p, int *q)
10096     {
10097         int t;
10098         t = *p;
10099         *p = *q;
10100         *q = t;
10101     }
10102     
10103     void vsetc(CType *type, int r, CValue *vc)
10104     {
10105         int v;
10106     
10107         if (vtop >= vstack + (VSTACK_SIZE - 1))
10108             error("memory full");
10109         /* cannot let cpu flags if other instruction are generated. Also
10110            avoid leaving VT_JMP anywhere except on the top of the stack
10111            because it would complicate the code generator. */
10112         if (vtop >= vstack) {
10113             v = vtop->r & VT_VALMASK;
10114             if (v == VT_CMP || (v & ~1) == VT_JMP)
10115                 gv(RC_INT);
10116         }
10117         vtop++;
10118         vtop->type = *type;
10119         vtop->r = r;
10120         vtop->r2 = VT_CONST;
10121         vtop->c = *vc;
10122     }
10123     
10124     /* push integer constant */
10125     void vpushi(int v)
10126     {
10127         CValue cval;
10128         cval.i = v;
10129         vsetc(&int_type, VT_CONST, &cval);
10130     }
10131     
10132     /* Return a static symbol pointing to a section */
10133     static Sym *get_sym_ref(CType *type, Section *sec, 
10134                             unsigned long offset, unsigned long size)
10135     {
10136         int v;
10137         Sym *sym;
10138     
10139         v = anon_sym++;
10140         sym = global_identifier_push(v, type->t | VT_STATIC, 0);
10141         sym->type.ref = type->ref;
10142         sym->r = VT_CONST | VT_SYM;
10143         put_extern_sym(sym, sec, offset, size);
10144         return sym;
10145     }
10146     
10147     /* push a reference to a section offset by adding a dummy symbol */
10148     static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
10149     {
10150         CValue cval;
10151     
10152         cval.ul = 0;
10153         vsetc(type, VT_CONST | VT_SYM, &cval);
10154         vtop->sym = get_sym_ref(type, sec, offset, size);
10155     }
10156     
10157     /* define a new external reference to a symbol 'v' of type 'u' */
10158     static Sym *external_global_sym(int v, CType *type, int r)
10159     {
10160         Sym *s;
10161     
10162         s = sym_find(v);
10163         if (!s) {
10164             /* push forward reference */
10165             s = global_identifier_push(v, type->t | VT_EXTERN, 0);
10166             s->type.ref = type->ref;
10167             s->r = r | VT_CONST | VT_SYM;
10168         }
10169         return s;
10170     }
10171     
10172     /* define a new external reference to a symbol 'v' of type 'u' */
10173     static Sym *external_sym(int v, CType *type, int r)
10174     {
10175         Sym *s;
10176     
10177         s = sym_find(v);
10178         if (!s) {
10179             /* push forward reference */
10180             s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
10181             s->type.t |= VT_EXTERN;
10182         } else {
10183             if (!is_compatible_types(&s->type, type))
10184                 error("incompatible types for redefinition of '%s'", 
10185                       get_tok_str(v, NULL));
10186         }
10187         return s;
10188     }
10189     
10190     /* push a reference to global symbol v */
10191     static void vpush_global_sym(CType *type, int v)
10192     {
10193         Sym *sym;
10194         CValue cval;
10195     
10196         sym = external_global_sym(v, type, 0);
10197         cval.ul = 0;
10198         vsetc(type, VT_CONST | VT_SYM, &cval);
10199         vtop->sym = sym;
10200     }
10201     
10202     void vset(CType *type, int r, int v)
10203     {
10204         CValue cval;
10205     
10206         cval.i = v;
10207         vsetc(type, r, &cval);
10208     }
10209     
10210     void vseti(int r, int v)
10211     {
10212         CType type;
10213         type.t = VT_INT;
10214         vset(&type, r, v);
10215     }
10216     
10217     void vswap(void)
10218     {
10219         SValue tmp;
10220     
10221         tmp = vtop[0];
10222         vtop[0] = vtop[-1];
10223         vtop[-1] = tmp;
10224     }
10225     
10226     void vpushv(SValue *v)
10227     {
10228         if (vtop >= vstack + (VSTACK_SIZE - 1))
10229             error("memory full");
10230         vtop++;
10231         *vtop = *v;
10232     }
10233     
10234     void vdup(void)
10235     {
10236         vpushv(vtop);
10237     }
10238     
10239     /* save r to the memory stack, and mark it as being free */
10240     void save_reg(int r)
10241     {
10242         int l, saved, size, align;
10243         SValue *p, sv;
10244         CType *type;
10245     
10246         /* modify all stack values */
10247         saved = 0;
10248         l = 0;
10249         for(p=vstack;p<=vtop;p++) {
10250             if ((p->r & VT_VALMASK) == r ||
10251                 (p->r2 & VT_VALMASK) == r) {
10252                 /* must save value on stack if not already done */
10253                 if (!saved) {
10254                     /* NOTE: must reload 'r' because r might be equal to r2 */
10255                     r = p->r & VT_VALMASK;
10256                     /* store register in the stack */
10257                     type = &p->type;
10258                     if ((p->r & VT_LVAL) || 
10259                         (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
10260                         type = &int_type;
10261                     size = type_size(type, &align);
10262                     loc = (loc - size) & -align;
10263                     sv.type.t = type->t;
10264                     sv.r = VT_LOCAL | VT_LVAL;
10265                     sv.c.ul = loc;
10266                     store(r, &sv);
10267     #ifdef TCC_TARGET_I386
10268                     /* x86 specific: need to pop fp register ST0 if saved */
10269                     if (r == TREG_ST0) {
10270                         o(0xd9dd); /* fstp %st(1) */
10271                     }
10272     #endif
10273                     /* special long long case */
10274                     if ((type->t & VT_BTYPE) == VT_LLONG) {
10275                         sv.c.ul += 4;
10276                         store(p->r2, &sv);
10277                     }
10278                     l = loc;
10279                     saved = 1;
10280                 }
10281                 /* mark that stack entry as being saved on the stack */
10282                 if (p->r & VT_LVAL) {
10283                     /* also clear the bounded flag because the
10284                        relocation address of the function was stored in
10285                        p->c.ul */
10286                     p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
10287                 } else {
10288                     p->r = lvalue_type(p->type.t) | VT_LOCAL;
10289                 }
10290                 p->r2 = VT_CONST;
10291                 p->c.ul = l;
10292             }
10293         }
10294     }
10295     
10296     /* find a register of class 'rc2' with at most one reference on stack.
10297      * If none, call get_reg(rc) */
10298     int get_reg_ex(int rc, int rc2) 
10299     {
10300         int r;
10301         SValue *p;
10302         
10303         for(r=0;r<NB_REGS;r++) {
10304             if (reg_classes[r] & rc2) {
10305                 int n;
10306                 n=0;
10307                 for(p = vstack; p <= vtop; p++) {
10308                     if ((p->r & VT_VALMASK) == r ||
10309                         (p->r2 & VT_VALMASK) == r)
10310                         n++;
10311                 }
10312                 if (n <= 1)
10313                     return r;
10314             }
10315         }
10316         return get_reg(rc);
10317     }
10318     
10319     /* find a free register of class 'rc'. If none, save one register */
10320     int get_reg(int rc)
10321     {
10322         int r;
10323         SValue *p;
10324     
10325         /* find a free register */
10326         for(r=0;r<NB_REGS;r++) {
10327             if (reg_classes[r] & rc) {
10328                 for(p=vstack;p<=vtop;p++) {
10329                     if ((p->r & VT_VALMASK) == r ||
10330                         (p->r2 & VT_VALMASK) == r)
10331                         goto notfound;
10332                 }
10333                 return r;
10334             }
10335         notfound: ;
10336         }
10337         
10338         /* no register left : free the first one on the stack (VERY
10339            IMPORTANT to start from the bottom to ensure that we don't
10340            spill registers used in gen_opi()) */
10341         for(p=vstack;p<=vtop;p++) {
10342             r = p->r & VT_VALMASK;
10343             if (r < VT_CONST && (reg_classes[r] & rc))
10344                 goto save_found;
10345             /* also look at second register (if long long) */
10346             r = p->r2 & VT_VALMASK;
10347             if (r < VT_CONST && (reg_classes[r] & rc)) {
10348             save_found:
10349                 save_reg(r);
10350                 return r;
10351             }
10352         }
10353         /* Should never comes here */
10354         return -1;
10355     }
10356     
10357     /* save registers up to (vtop - n) stack entry */
10358     void save_regs(int n)
10359     {
10360         int r;
10361         SValue *p, *p1;
10362         p1 = vtop - n;
10363         for(p = vstack;p <= p1; p++) {
10364             r = p->r & VT_VALMASK;
10365             if (r < VT_CONST) {
10366                 save_reg(r);
10367             }
10368         }
10369     }
10370     
10371     /* move register 's' to 'r', and flush previous value of r to memory
10372        if needed */
10373     void move_reg(int r, int s)
10374     {
10375         SValue sv;
10376     
10377         if (r != s) {
10378             save_reg(r);
10379             sv.type.t = VT_INT;
10380             sv.r = s;
10381             sv.c.ul = 0;
10382             load(r, &sv);
10383         }
10384     }
10385     
10386     /* get address of vtop (vtop MUST BE an lvalue) */
10387     void gaddrof(void)
10388     {
10389         vtop->r &= ~VT_LVAL;
10390         /* tricky: if saved lvalue, then we can go back to lvalue */
10391         if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
10392             vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
10393     }
10394     
10395     #ifdef CONFIG_TCC_BCHECK
10396     /* generate lvalue bound code */
10397     void gbound(void)
10398     {
10399         int lval_type;
10400         CType type1;
10401     
10402         vtop->r &= ~VT_MUSTBOUND;
10403         /* if lvalue, then use checking code before dereferencing */
10404         if (vtop->r & VT_LVAL) {
10405             /* if not VT_BOUNDED value, then make one */
10406             if (!(vtop->r & VT_BOUNDED)) {
10407                 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
10408                 /* must save type because we must set it to int to get pointer */
10409                 type1 = vtop->type;
10410                 vtop->type.t = VT_INT;
10411                 gaddrof();
10412                 vpushi(0);
10413                 gen_bounded_ptr_add();
10414                 vtop->r |= lval_type;
10415                 vtop->type = type1;
10416             }
10417             /* then check for dereferencing */
10418             gen_bounded_ptr_deref();
10419         }
10420     }
10421     #endif
10422     
10423     /* store vtop a register belonging to class 'rc'. lvalues are
10424        converted to values. Cannot be used if cannot be converted to
10425        register value (such as structures). */
10426     int gv(int rc)
10427     {
10428         int r, r2, rc2, bit_pos, bit_size, size, align, i;
10429         unsigned long long ll;
10430     
10431         /* NOTE: get_reg can modify vstack[] */
10432         if (vtop->type.t & VT_BITFIELD) {
10433             bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
10434             bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
10435             /* remove bit field info to avoid loops */
10436             vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
10437             /* generate shifts */
10438             vpushi(32 - (bit_pos + bit_size));
10439             gen_op(TOK_SHL);
10440             vpushi(32 - bit_size);
10441             /* NOTE: transformed to SHR if unsigned */
10442             gen_op(TOK_SAR);
10443             r = gv(rc);
10444         } else {
10445             if (is_float(vtop->type.t) && 
10446                 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
10447                 Sym *sym;
10448                 int *ptr;
10449                 unsigned long offset;
10450                 
10451                 /* XXX: unify with initializers handling ? */
10452                 /* CPUs usually cannot use float constants, so we store them
10453                    generically in data segment */
10454                 size = type_size(&vtop->type, &align);
10455                 offset = (data_section->data_offset + align - 1) & -align;
10456                 data_section->data_offset = offset;
10457                 /* XXX: not portable yet */
10458                 ptr = section_ptr_add(data_section, size);
10459                 size = size >> 2;
10460                 for(i=0;i<size;i++)
10461                     ptr[i] = vtop->c.tab[i];
10462                 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
10463                 vtop->r |= VT_LVAL | VT_SYM;
10464                 vtop->sym = sym;
10465                 vtop->c.ul = 0;
10466             }
10467     #ifdef CONFIG_TCC_BCHECK
10468             if (vtop->r & VT_MUSTBOUND) 
10469                 gbound();
10470     #endif
10471     
10472             r = vtop->r & VT_VALMASK;
10473             /* need to reload if:
10474                - constant
10475                - lvalue (need to dereference pointer)
10476                - already a register, but not in the right class */
10477             if (r >= VT_CONST || 
10478                 (vtop->r & VT_LVAL) ||
10479                 !(reg_classes[r] & rc) ||
10480                 ((vtop->type.t & VT_BTYPE) == VT_LLONG && 
10481                  !(reg_classes[vtop->r2] & rc))) {
10482                 r = get_reg(rc);
10483                 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
10484                     /* two register type load : expand to two words
10485                        temporarily */
10486                     if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
10487                         /* load constant */
10488                         ll = vtop->c.ull;
10489                         vtop->c.ui = ll; /* first word */
10490                         load(r, vtop);
10491                         vtop->r = r; /* save register value */
10492                         vpushi(ll >> 32); /* second word */
10493                     } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
10494                                (vtop->r & VT_LVAL)) {
10495                         /* We do not want to modifier the long long
10496                            pointer here, so the safest (and less
10497                            efficient) is to save all the other registers
10498                            in the stack. XXX: totally inefficient. */
10499                         save_regs(1);
10500                         /* load from memory */
10501                         load(r, vtop);
10502                         vdup();
10503                         vtop[-1].r = r; /* save register value */
10504                         /* increment pointer to get second word */
10505                         vtop->type.t = VT_INT;
10506                         gaddrof();
10507                         vpushi(4);
10508                         gen_op('+');
10509                         vtop->r |= VT_LVAL;
10510                     } else {
10511                         /* move registers */
10512                         load(r, vtop);
10513                         vdup();
10514                         vtop[-1].r = r; /* save register value */
10515                         vtop->r = vtop[-1].r2;
10516                     }
10517                     /* allocate second register */
10518                     rc2 = RC_INT;
10519                     if (rc == RC_IRET)
10520                         rc2 = RC_LRET;
10521                     r2 = get_reg(rc2);
10522                     load(r2, vtop);
10523                     vpop();
10524                     /* write second register */
10525                     vtop->r2 = r2;
10526                 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
10527                     int t1, t;
10528                     /* lvalue of scalar type : need to use lvalue type
10529                        because of possible cast */
10530                     t = vtop->type.t;
10531                     t1 = t;
10532                     /* compute memory access type */
10533                     if (vtop->r & VT_LVAL_BYTE)
10534                         t = VT_BYTE;
10535                     else if (vtop->r & VT_LVAL_SHORT)
10536                         t = VT_SHORT;
10537                     if (vtop->r & VT_LVAL_UNSIGNED)
10538                         t |= VT_UNSIGNED;
10539                     vtop->type.t = t;
10540                     load(r, vtop);
10541                     /* restore wanted type */
10542                     vtop->type.t = t1;
10543                 } else {
10544                     /* one register type load */
10545                     load(r, vtop);
10546                 }
10547             }
10548             vtop->r = r;
10549     #ifdef TCC_TARGET_C67
10550             /* uses register pairs for doubles */
10551             if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) 
10552                 vtop->r2 = r+1;
10553     #endif
10554         }
10555         return r;
10556     }
10557     
10558     /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
10559     void gv2(int rc1, int rc2)
10560     {
10561         int v;
10562     
10563         /* generate more generic register first. But VT_JMP or VT_CMP
10564            values must be generated first in all cases to avoid possible
10565            reload errors */
10566         v = vtop[0].r & VT_VALMASK;
10567         if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
10568             vswap();
10569             gv(rc1);
10570             vswap();
10571             gv(rc2);
10572             /* test if reload is needed for first register */
10573             if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
10574                 vswap();
10575                 gv(rc1);
10576                 vswap();
10577             }
10578         } else {
10579             gv(rc2);
10580             vswap();
10581             gv(rc1);
10582             vswap();
10583             /* test if reload is needed for first register */
10584             if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
10585                 gv(rc2);
10586             }
10587         }
10588     }
10589     
10590     /* expand long long on stack in two int registers */
10591     void lexpand(void)
10592     {
10593         int u;
10594     
10595         u = vtop->type.t & VT_UNSIGNED;
10596         gv(RC_INT);
10597         vdup();
10598         vtop[0].r = vtop[-1].r2;
10599         vtop[0].r2 = VT_CONST;
10600         vtop[-1].r2 = VT_CONST;
10601         vtop[0].type.t = VT_INT | u;
10602         vtop[-1].type.t = VT_INT | u;
10603     }
10604     
10605     #ifdef TCC_TARGET_ARM
10606     /* expand long long on stack */
10607     void lexpand_nr(void)
10608     {
10609         int u,v;
10610     
10611         u = vtop->type.t & VT_UNSIGNED;
10612         vdup();
10613         vtop->r2 = VT_CONST;
10614         vtop->type.t = VT_INT | u;
10615         v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
10616         if (v == VT_CONST) {
10617           vtop[-1].c.ui = vtop->c.ull;
10618           vtop->c.ui = vtop->c.ull >> 32;
10619           vtop->r = VT_CONST;
10620         } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
10621           vtop->c.ui += 4;
10622           vtop->r = vtop[-1].r;
10623         } else if (v > VT_CONST) {
10624           vtop--;
10625           lexpand();
10626         } else
10627           vtop->r = vtop[-1].r2;
10628         vtop[-1].r2 = VT_CONST;
10629         vtop[-1].type.t = VT_INT | u;
10630     }
10631     #endif
10632     
10633     /* build a long long from two ints */
10634     void lbuild(int t)
10635     {
10636         gv2(RC_INT, RC_INT);
10637         vtop[-1].r2 = vtop[0].r;
10638         vtop[-1].type.t = t;
10639         vpop();
10640     }
10641     
10642     /* rotate n first stack elements to the bottom 
10643        I1 ... In -> I2 ... In I1 [top is right]
10644     */
10645     void vrotb(int n)
10646     {
10647         int i;
10648         SValue tmp;
10649     
10650         tmp = vtop[-n + 1];
10651         for(i=-n+1;i!=0;i++)
10652             vtop[i] = vtop[i+1];
10653         vtop[0] = tmp;
10654     }
10655     
10656     /* rotate n first stack elements to the top 
10657        I1 ... In -> In I1 ... I(n-1)  [top is right]
10658      */
10659     void vrott(int n)
10660     {
10661         int i;
10662         SValue tmp;
10663     
10664         tmp = vtop[0];
10665         for(i = 0;i < n - 1; i++)
10666             vtop[-i] = vtop[-i - 1];
10667         vtop[-n + 1] = tmp;
10668     }
10669     
10670     #ifdef TCC_TARGET_ARM
10671     /* like vrott but in other direction
10672        In ... I1 -> I(n-1) ... I1 In  [top is right]
10673      */
10674     void vnrott(int n)
10675     {
10676         int i;
10677         SValue tmp;
10678     
10679         tmp = vtop[-n + 1];
10680         for(i = n - 1; i > 0; i--)
10681             vtop[-i] = vtop[-i + 1];
10682         vtop[0] = tmp;
10683     }
10684     #endif
10685     
10686     /* pop stack value */
10687     void vpop(void)
10688     {
10689         int v;
10690         v = vtop->r & VT_VALMASK;
10691     #ifdef TCC_TARGET_I386
10692         /* for x86, we need to pop the FP stack */
10693         if (v == TREG_ST0 && !nocode_wanted) {
10694             o(0xd9dd); /* fstp %st(1) */
10695         } else
10696     #endif
10697         if (v == VT_JMP || v == VT_JMPI) {
10698             /* need to put correct jump if && or || without test */
10699             gsym(vtop->c.ul);
10700         }
10701         vtop--;
10702     }
10703     
10704     /* convert stack entry to register and duplicate its value in another
10705        register */
10706     void gv_dup(void)
10707     {
10708         int rc, t, r, r1;
10709         SValue sv;
10710     
10711         t = vtop->type.t;
10712         if ((t & VT_BTYPE) == VT_LLONG) {
10713             lexpand();
10714             gv_dup();
10715             vswap();
10716             vrotb(3);
10717             gv_dup();
10718             vrotb(4);
10719             /* stack: H L L1 H1 */
10720             lbuild(t);
10721             vrotb(3);
10722             vrotb(3);
10723             vswap();
10724             lbuild(t);
10725             vswap();
10726         } else {
10727             /* duplicate value */
10728             rc = RC_INT;
10729             sv.type.t = VT_INT;
10730             if (is_float(t)) {
10731                 rc = RC_FLOAT;
10732                 sv.type.t = t;
10733             }
10734             r = gv(rc);
10735             r1 = get_reg(rc);
10736             sv.r = r;
10737             sv.c.ul = 0;
10738             load(r1, &sv); /* move r to r1 */
10739             vdup();
10740             /* duplicates value */
10741             vtop->r = r1;
10742         }
10743     }
10744     
10745     /* generate CPU independent (unsigned) long long operations */
10746     void gen_opl(int op)
10747     {
10748         int t, a, b, op1, c, i;
10749         int func;
10750         SValue tmp;
10751     
10752         switch(op) {
10753         case '/':
10754         case TOK_PDIV:
10755             func = TOK___divdi3;
10756             goto gen_func;
10757         case TOK_UDIV:
10758             func = TOK___udivdi3;
10759             goto gen_func;
10760         case '%':
10761             func = TOK___moddi3;
10762             goto gen_func;
10763         case TOK_UMOD:
10764             func = TOK___umoddi3;
10765         gen_func:
10766             /* call generic long long function */
10767             vpush_global_sym(&func_old_type, func);
10768             vrott(3);
10769             gfunc_call(2);
10770             vpushi(0);
10771             vtop->r = REG_IRET;
10772             vtop->r2 = REG_LRET;
10773             break;
10774         case '^':
10775         case '&':
10776         case '|':
10777         case '*':
10778         case '+':
10779         case '-':
10780             t = vtop->type.t;
10781             vswap();
10782             lexpand();
10783             vrotb(3);
10784             lexpand();
10785             /* stack: L1 H1 L2 H2 */
10786             tmp = vtop[0];
10787             vtop[0] = vtop[-3];
10788             vtop[-3] = tmp;
10789             tmp = vtop[-2];
10790             vtop[-2] = vtop[-3];
10791             vtop[-3] = tmp;
10792             vswap();
10793             /* stack: H1 H2 L1 L2 */
10794             if (op == '*') {
10795                 vpushv(vtop - 1);
10796                 vpushv(vtop - 1);
10797                 gen_op(TOK_UMULL);
10798                 lexpand();
10799                 /* stack: H1 H2 L1 L2 ML MH */
10800                 for(i=0;i<4;i++)
10801                     vrotb(6);
10802                 /* stack: ML MH H1 H2 L1 L2 */
10803                 tmp = vtop[0];
10804                 vtop[0] = vtop[-2];
10805                 vtop[-2] = tmp;
10806                 /* stack: ML MH H1 L2 H2 L1 */
10807                 gen_op('*');
10808                 vrotb(3);
10809                 vrotb(3);
10810                 gen_op('*');
10811                 /* stack: ML MH M1 M2 */
10812                 gen_op('+');
10813                 gen_op('+');
10814             } else if (op == '+' || op == '-') {
10815                 /* XXX: add non carry method too (for MIPS or alpha) */
10816                 if (op == '+')
10817                     op1 = TOK_ADDC1;
10818                 else
10819                     op1 = TOK_SUBC1;
10820                 gen_op(op1);
10821                 /* stack: H1 H2 (L1 op L2) */
10822                 vrotb(3);
10823                 vrotb(3);
10824                 gen_op(op1 + 1); /* TOK_xxxC2 */
10825             } else {
10826                 gen_op(op);
10827                 /* stack: H1 H2 (L1 op L2) */
10828                 vrotb(3);
10829                 vrotb(3);
10830                 /* stack: (L1 op L2) H1 H2 */
10831                 gen_op(op);
10832                 /* stack: (L1 op L2) (H1 op H2) */
10833             }
10834             /* stack: L H */
10835             lbuild(t);
10836             break;
10837         case TOK_SAR:
10838         case TOK_SHR:
10839         case TOK_SHL:
10840             if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
10841                 t = vtop[-1].type.t;
10842                 vswap();
10843                 lexpand();
10844                 vrotb(3);
10845                 /* stack: L H shift */
10846                 c = (int)vtop->c.i;
10847                 /* constant: simpler */
10848                 /* NOTE: all comments are for SHL. the other cases are
10849                    done by swaping words */
10850                 vpop();
10851                 if (op != TOK_SHL)
10852                     vswap();
10853                 if (c >= 32) {
10854                     /* stack: L H */
10855                     vpop();
10856                     if (c > 32) {
10857                         vpushi(c - 32);
10858                         gen_op(op);
10859                     }
10860                     if (op != TOK_SAR) {
10861                         vpushi(0);
10862                     } else {
10863                         gv_dup();
10864                         vpushi(31);
10865                         gen_op(TOK_SAR);
10866                     }
10867                     vswap();
10868                 } else {
10869                     vswap();
10870                     gv_dup();
10871                     /* stack: H L L */
10872                     vpushi(c);
10873                     gen_op(op);
10874                     vswap();
10875                     vpushi(32 - c);
10876                     if (op == TOK_SHL)
10877                         gen_op(TOK_SHR);
10878                     else
10879                         gen_op(TOK_SHL);
10880                     vrotb(3);
10881                     /* stack: L L H */
10882                     vpushi(c);
10883                     if (op == TOK_SHL)
10884                         gen_op(TOK_SHL);
10885                     else
10886                         gen_op(TOK_SHR);
10887                     gen_op('|');
10888                 }
10889                 if (op != TOK_SHL)
10890                     vswap();
10891                 lbuild(t);
10892             } else {
10893                 /* XXX: should provide a faster fallback on x86 ? */
10894                 switch(op) {
10895                 case TOK_SAR:
10896                     func = TOK___sardi3;
10897                     goto gen_func;
10898                 case TOK_SHR:
10899                     func = TOK___shrdi3;
10900                     goto gen_func;
10901                 case TOK_SHL:
10902                     func = TOK___shldi3;
10903                     goto gen_func;
10904                 }
10905             }
10906             break;
10907         default:
10908             /* compare operations */
10909             t = vtop->type.t;
10910             vswap();
10911             lexpand();
10912             vrotb(3);
10913             lexpand();
10914             /* stack: L1 H1 L2 H2 */
10915             tmp = vtop[-1];
10916             vtop[-1] = vtop[-2];
10917             vtop[-2] = tmp;
10918             /* stack: L1 L2 H1 H2 */
10919             /* compare high */
10920             op1 = op;
10921             /* when values are equal, we need to compare low words. since
10922                the jump is inverted, we invert the test too. */
10923             if (op1 == TOK_LT)
10924                 op1 = TOK_LE;
10925             else if (op1 == TOK_GT)
10926                 op1 = TOK_GE;
10927             else if (op1 == TOK_ULT)
10928                 op1 = TOK_ULE;
10929             else if (op1 == TOK_UGT)
10930                 op1 = TOK_UGE;
10931             a = 0;
10932             b = 0;
10933             gen_op(op1);
10934             if (op1 != TOK_NE) {
10935                 a = gtst(1, 0);
10936             }
10937             if (op != TOK_EQ) {
10938                 /* generate non equal test */
10939                 /* XXX: NOT PORTABLE yet */
10940                 if (a == 0) {
10941                     b = gtst(0, 0);
10942                 } else {
10943     #if defined(TCC_TARGET_I386)
10944                     b = psym(0x850f, 0);
10945     #elif defined(TCC_TARGET_ARM)
10946     		b = ind;
10947     		o(0x1A000000 | encbranch(ind, 0, 1));
10948     #elif defined(TCC_TARGET_C67)
10949                     error("not implemented");
10950     #else
10951     #error not supported
10952     #endif
10953                 }
10954             }
10955             /* compare low. Always unsigned */
10956             op1 = op;
10957             if (op1 == TOK_LT)
10958                 op1 = TOK_ULT;
10959             else if (op1 == TOK_LE)
10960                 op1 = TOK_ULE;
10961             else if (op1 == TOK_GT)
10962                 op1 = TOK_UGT;
10963             else if (op1 == TOK_GE)
10964                 op1 = TOK_UGE;
10965             gen_op(op1);
10966             a = gtst(1, a);
10967             gsym(b);
10968             vseti(VT_JMPI, a);
10969             break;
10970         }
10971     }
10972     
10973     /* handle integer constant optimizations and various machine
10974        independent opt */
10975     void gen_opic(int op)
10976     {
10977         int fc, c1, c2, n;
10978         SValue *v1, *v2;
10979     
10980         v1 = vtop - 1;
10981         v2 = vtop;
10982         /* currently, we cannot do computations with forward symbols */
10983         c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
10984         c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
10985         if (c1 && c2) {
10986             fc = v2->c.i;
10987             switch(op) {
10988             case '+': v1->c.i += fc; break;
10989             case '-': v1->c.i -= fc; break;
10990             case '&': v1->c.i &= fc; break;
10991             case '^': v1->c.i ^= fc; break;
10992             case '|': v1->c.i |= fc; break;
10993             case '*': v1->c.i *= fc; break;
10994     
10995             case TOK_PDIV:
10996             case '/':
10997             case '%':
10998             case TOK_UDIV:
10999             case TOK_UMOD:
11000                 /* if division by zero, generate explicit division */
11001                 if (fc == 0) {
11002                     if (const_wanted)
11003                         error("division by zero in constant");
11004                     goto general_case;
11005                 }
11006                 switch(op) {
11007                 default: v1->c.i /= fc; break;
11008                 case '%': v1->c.i %= fc; break;
11009                 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
11010                 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
11011                 }
11012                 break;
11013             case TOK_SHL: v1->c.i <<= fc; break;
11014             case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
11015             case TOK_SAR: v1->c.i >>= fc; break;
11016                 /* tests */
11017             case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
11018             case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
11019             case TOK_EQ: v1->c.i = v1->c.i == fc; break;
11020             case TOK_NE: v1->c.i = v1->c.i != fc; break;
11021             case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
11022             case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
11023             case TOK_LT: v1->c.i = v1->c.i < fc; break;
11024             case TOK_GE: v1->c.i = v1->c.i >= fc; break;
11025             case TOK_LE: v1->c.i = v1->c.i <= fc; break;
11026             case TOK_GT: v1->c.i = v1->c.i > fc; break;
11027                 /* logical */
11028             case TOK_LAND: v1->c.i = v1->c.i && fc; break;
11029             case TOK_LOR: v1->c.i = v1->c.i || fc; break;
11030             default:
11031                 goto general_case;
11032             }
11033             vtop--;
11034         } else {
11035             /* if commutative ops, put c2 as constant */
11036             if (c1 && (op == '+' || op == '&' || op == '^' || 
11037                        op == '|' || op == '*')) {
11038                 vswap();
11039                 swap(&c1, &c2);
11040             }
11041             fc = vtop->c.i;
11042             if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV || 
11043                          op == TOK_PDIV) && 
11044                         fc == 1) ||
11045                        ((op == '+' || op == '-' || op == '|' || op == '^' || 
11046                          op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) && 
11047                         fc == 0) ||
11048                        (op == '&' && 
11049                         fc == -1))) {
11050                 /* nothing to do */
11051                 vtop--;
11052             } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
11053                 /* try to use shifts instead of muls or divs */
11054                 if (fc > 0 && (fc & (fc - 1)) == 0) {
11055                     n = -1;
11056                     while (fc) {
11057                         fc >>= 1;
11058                         n++;
11059                     }
11060                     vtop->c.i = n;
11061                     if (op == '*')
11062                         op = TOK_SHL;
11063                     else if (op == TOK_PDIV)
11064                         op = TOK_SAR;
11065                     else
11066                         op = TOK_SHR;
11067                 }
11068                 goto general_case;
11069             } else if (c2 && (op == '+' || op == '-') &&
11070                        (vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == 
11071                        (VT_CONST | VT_SYM)) {
11072                 /* symbol + constant case */
11073                 if (op == '-')
11074                     fc = -fc;
11075                 vtop--;
11076                 vtop->c.i += fc;
11077             } else {
11078             general_case:
11079                 if (!nocode_wanted) {
11080                     /* call low level op generator */
11081                     gen_opi(op);
11082                 } else {
11083                     vtop--;
11084                 }
11085             }
11086         }
11087     }
11088     
11089     /* generate a floating point operation with constant propagation */
11090     void gen_opif(int op)
11091     {
11092         int c1, c2;
11093         SValue *v1, *v2;
11094         long double f1, f2;
11095     
11096         v1 = vtop - 1;
11097         v2 = vtop;
11098         /* currently, we cannot do computations with forward symbols */
11099         c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
11100         c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
11101         if (c1 && c2) {
11102             if (v1->type.t == VT_FLOAT) {
11103                 f1 = v1->c.f;
11104                 f2 = v2->c.f;
11105             } else if (v1->type.t == VT_DOUBLE) {
11106                 f1 = v1->c.d;
11107                 f2 = v2->c.d;
11108             } else {
11109                 f1 = v1->c.ld;
11110                 f2 = v2->c.ld;
11111             }
11112     
11113             /* NOTE: we only do constant propagation if finite number (not
11114                NaN or infinity) (ANSI spec) */
11115             if (!ieee_finite(f1) || !ieee_finite(f2))
11116                 goto general_case;
11117     
11118             switch(op) {
11119             case '+': f1 += f2; break;
11120             case '-': f1 -= f2; break;
11121             case '*': f1 *= f2; break;
11122             case '/': 
11123                 if (f2 == 0.0) {
11124                     if (const_wanted)
11125                         error("division by zero in constant");
11126                     goto general_case;
11127                 }
11128                 f1 /= f2; 
11129                 break;
11130                 /* XXX: also handles tests ? */
11131             default:
11132                 goto general_case;
11133             }
11134             /* XXX: overflow test ? */
11135             if (v1->type.t == VT_FLOAT) {
11136                 v1->c.f = f1;
11137             } else if (v1->type.t == VT_DOUBLE) {
11138                 v1->c.d = f1;
11139             } else {
11140                 v1->c.ld = f1;
11141             }
11142             vtop--;
11143         } else {
11144         general_case:
11145             if (!nocode_wanted) {
11146                 gen_opf(op);
11147             } else {
11148                 vtop--;
11149             }
11150         }
11151     }
11152     
11153     /* return the pointed type of t */
11154     static inline CType *pointed_type(CType *type)
11155     {
11156         return &type->ref->type;
11157     }
11158     
11159     static int pointed_size(CType *type)
11160     {
11161         int align;
11162         return type_size(pointed_type(type), &align);
11163     }
11164     
11165     static inline int is_null_pointer(SValue *p)
11166     {
11167         if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
11168             return 0;
11169         return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
11170             ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0);
11171     }
11172     
11173     static inline int is_integer_btype(int bt)
11174     {
11175         return (bt == VT_BYTE || bt == VT_SHORT || 
11176                 bt == VT_INT || bt == VT_LLONG);
11177     }
11178     
11179     /* check types for comparison or substraction of pointers */
11180     static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
11181     {
11182         CType *type1, *type2, tmp_type1, tmp_type2;
11183         int bt1, bt2;
11184         
11185         /* null pointers are accepted for all comparisons as gcc */
11186         if (is_null_pointer(p1) || is_null_pointer(p2))
11187             return;
11188         type1 = &p1->type;
11189         type2 = &p2->type;
11190         bt1 = type1->t & VT_BTYPE;
11191         bt2 = type2->t & VT_BTYPE;
11192         /* accept comparison between pointer and integer with a warning */
11193         if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
11194             warning("comparison between pointer and integer");
11195             return;
11196         }
11197     
11198         /* both must be pointers or implicit function pointers */
11199         if (bt1 == VT_PTR) {
11200             type1 = pointed_type(type1);
11201         } else if (bt1 != VT_FUNC) 
11202             goto invalid_operands;
11203     
11204         if (bt2 == VT_PTR) {
11205             type2 = pointed_type(type2);
11206         } else if (bt2 != VT_FUNC) { 
11207         invalid_operands:
11208             error("invalid operands to binary %s", get_tok_str(op, NULL));
11209         }
11210         if ((type1->t & VT_BTYPE) == VT_VOID || 
11211             (type2->t & VT_BTYPE) == VT_VOID)
11212             return;
11213         tmp_type1 = *type1;
11214         tmp_type2 = *type2;
11215         tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
11216         tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
11217         if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
11218             /* gcc-like error if '-' is used */
11219             if (op == '-')
11220                 goto invalid_operands;
11221             else
11222                 warning("comparison of distinct pointer types lacks a cast");
11223         }
11224     }
11225     
11226     /* generic gen_op: handles types problems */
11227     void gen_op(int op)
11228     {
11229         int u, t1, t2, bt1, bt2, t;
11230         CType type1;
11231     
11232         t1 = vtop[-1].type.t;
11233         t2 = vtop[0].type.t;
11234         bt1 = t1 & VT_BTYPE;
11235         bt2 = t2 & VT_BTYPE;
11236             
11237         if (bt1 == VT_PTR || bt2 == VT_PTR) {
11238             /* at least one operand is a pointer */
11239             /* relationnal op: must be both pointers */
11240             if (op >= TOK_ULT && op <= TOK_GT) {
11241                 check_comparison_pointer_types(vtop - 1, vtop, op);
11242                 /* pointers are handled are unsigned */
11243                 t = VT_INT | VT_UNSIGNED;
11244                 goto std_op;
11245             }
11246             /* if both pointers, then it must be the '-' op */
11247             if (bt1 == VT_PTR && bt2 == VT_PTR) {
11248                 if (op != '-')
11249                     error("cannot use pointers here");
11250                 check_comparison_pointer_types(vtop - 1, vtop, op);
11251                 /* XXX: check that types are compatible */
11252                 u = pointed_size(&vtop[-1].type);
11253                 gen_opic(op);
11254                 /* set to integer type */
11255                 vtop->type.t = VT_INT; 
11256                 vpushi(u);
11257                 gen_op(TOK_PDIV);
11258             } else {
11259                 /* exactly one pointer : must be '+' or '-'. */
11260                 if (op != '-' && op != '+')
11261                     error("cannot use pointers here");
11262                 /* Put pointer as first operand */
11263                 if (bt2 == VT_PTR) {
11264                     vswap();
11265                     swap(&t1, &t2);
11266                 }
11267                 type1 = vtop[-1].type;
11268                 /* XXX: cast to int ? (long long case) */
11269                 vpushi(pointed_size(&vtop[-1].type));
11270                 gen_op('*');
11271     #ifdef CONFIG_TCC_BCHECK
11272                 /* if evaluating constant expression, no code should be
11273                    generated, so no bound check */
11274                 if (do_bounds_check && !const_wanted) {
11275                     /* if bounded pointers, we generate a special code to
11276                        test bounds */
11277                     if (op == '-') {
11278                         vpushi(0);
11279                         vswap();
11280                         gen_op('-');
11281                     }
11282                     gen_bounded_ptr_add();
11283                 } else
11284     #endif
11285                 {
11286                     gen_opic(op);
11287                 }
11288                 /* put again type if gen_opic() swaped operands */
11289                 vtop->type = type1;
11290             }
11291         } else if (is_float(bt1) || is_float(bt2)) {
11292             /* compute bigger type and do implicit casts */
11293             if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
11294                 t = VT_LDOUBLE;
11295             } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
11296                 t = VT_DOUBLE;
11297             } else {
11298                 t = VT_FLOAT;
11299             }
11300             /* floats can only be used for a few operations */
11301             if (op != '+' && op != '-' && op != '*' && op != '/' &&
11302                 (op < TOK_ULT || op > TOK_GT))
11303                 error("invalid operands for binary operation");
11304             goto std_op;
11305         } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
11306             /* cast to biggest op */
11307             t = VT_LLONG;
11308             /* convert to unsigned if it does not fit in a long long */
11309             if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
11310                 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
11311                 t |= VT_UNSIGNED;
11312             goto std_op;
11313         } else {
11314             /* integer operations */
11315             t = VT_INT;
11316             /* convert to unsigned if it does not fit in an integer */
11317             if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
11318                 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
11319                 t |= VT_UNSIGNED;
11320         std_op:
11321             /* XXX: currently, some unsigned operations are explicit, so
11322                we modify them here */
11323             if (t & VT_UNSIGNED) {
11324                 if (op == TOK_SAR)
11325                     op = TOK_SHR;
11326                 else if (op == '/')
11327                     op = TOK_UDIV;
11328                 else if (op == '%')
11329                     op = TOK_UMOD;
11330                 else if (op == TOK_LT)
11331                     op = TOK_ULT;
11332                 else if (op == TOK_GT)
11333                     op = TOK_UGT;
11334                 else if (op == TOK_LE)
11335                     op = TOK_ULE;
11336                 else if (op == TOK_GE)
11337                     op = TOK_UGE;
11338             }
11339             vswap();
11340             type1.t = t;
11341             gen_cast(&type1);
11342             vswap();
11343             /* special case for shifts and long long: we keep the shift as
11344                an integer */
11345             if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
11346                 type1.t = VT_INT;
11347             gen_cast(&type1);
11348             if (is_float(t))
11349                 gen_opif(op);
11350             else if ((t & VT_BTYPE) == VT_LLONG)
11351                 gen_opl(op);
11352             else
11353                 gen_opic(op);
11354             if (op >= TOK_ULT && op <= TOK_GT) {
11355                 /* relationnal op: the result is an int */
11356                 vtop->type.t = VT_INT;
11357             } else {
11358                 vtop->type.t = t;
11359             }
11360         }
11361     }
11362     
11363     /* generic itof for unsigned long long case */
11364     void gen_cvt_itof1(int t)
11365     {
11366         if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == 
11367             (VT_LLONG | VT_UNSIGNED)) {
11368     
11369             if (t == VT_FLOAT)
11370                 vpush_global_sym(&func_old_type, TOK___ulltof);
11371             else if (t == VT_DOUBLE)
11372                 vpush_global_sym(&func_old_type, TOK___ulltod);
11373             else
11374                 vpush_global_sym(&func_old_type, TOK___ulltold);
11375             vrott(2);
11376             gfunc_call(1);
11377             vpushi(0);
11378             vtop->r = REG_FRET;
11379         } else {
11380             gen_cvt_itof(t);
11381         }
11382     }
11383     
11384     /* generic ftoi for unsigned long long case */
11385     void gen_cvt_ftoi1(int t)
11386     {
11387         int st;
11388     
11389         if (t == (VT_LLONG | VT_UNSIGNED)) {
11390             /* not handled natively */
11391             st = vtop->type.t & VT_BTYPE;
11392             if (st == VT_FLOAT)
11393                 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
11394             else if (st == VT_DOUBLE)
11395                 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
11396             else
11397                 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
11398             vrott(2);
11399             gfunc_call(1);
11400             vpushi(0);
11401             vtop->r = REG_IRET;
11402             vtop->r2 = REG_LRET;
11403         } else {
11404             gen_cvt_ftoi(t);
11405         }
11406     }
11407     
11408     /* force char or short cast */
11409     void force_charshort_cast(int t)
11410     {
11411         int bits, dbt;
11412         dbt = t & VT_BTYPE;
11413         /* XXX: add optimization if lvalue : just change type and offset */
11414         if (dbt == VT_BYTE)
11415             bits = 8;
11416         else
11417             bits = 16;
11418         if (t & VT_UNSIGNED) {
11419             vpushi((1 << bits) - 1);
11420             gen_op('&');
11421         } else {
11422             bits = 32 - bits;
11423             vpushi(bits);
11424             gen_op(TOK_SHL);
11425             vpushi(bits);
11426             gen_op(TOK_SAR);
11427         }
11428     }
11429     
11430     /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
11431     static void gen_cast(CType *type)
11432     {
11433         int sbt, dbt, sf, df, c;
11434     
11435         /* special delayed cast for char/short */
11436         /* XXX: in some cases (multiple cascaded casts), it may still
11437            be incorrect */
11438         if (vtop->r & VT_MUSTCAST) {
11439             vtop->r &= ~VT_MUSTCAST;
11440             force_charshort_cast(vtop->type.t);
11441         }
11442     
11443         /* bitfields first get cast to ints */
11444         if (vtop->type.t & VT_BITFIELD) {
11445             gv(RC_INT);
11446         }
11447     
11448         dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
11449         sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
11450     
11451         if (sbt != dbt && !nocode_wanted) {
11452             sf = is_float(sbt);
11453             df = is_float(dbt);
11454             c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
11455             if (sf && df) {
11456                 /* convert from fp to fp */
11457                 if (c) {
11458                     /* constant case: we can do it now */
11459                     /* XXX: in ISOC, cannot do it if error in convert */
11460                     if (dbt == VT_FLOAT && sbt == VT_DOUBLE) 
11461                         vtop->c.f = (float)vtop->c.d;
11462                     else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE) 
11463                         vtop->c.f = (float)vtop->c.ld;
11464                     else if (dbt == VT_DOUBLE && sbt == VT_FLOAT) 
11465                         vtop->c.d = (double)vtop->c.f;
11466                     else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE) 
11467                         vtop->c.d = (double)vtop->c.ld;
11468                     else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT) 
11469                         vtop->c.ld = (long double)vtop->c.f;
11470                     else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE) 
11471                         vtop->c.ld = (long double)vtop->c.d;
11472                 } else {
11473                     /* non constant case: generate code */
11474                     gen_cvt_ftof(dbt);
11475                 }
11476             } else if (df) {
11477                 /* convert int to fp */
11478                 if (c) {
11479                     switch(sbt) {
11480                     case VT_LLONG | VT_UNSIGNED:
11481                     case VT_LLONG:
11482                         /* XXX: add const cases for long long */
11483                         goto do_itof;
11484                     case VT_INT | VT_UNSIGNED:
11485                         switch(dbt) {
11486                         case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
11487                         case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
11488                         case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
11489                         }
11490                         break;
11491                     default:
11492                         switch(dbt) {
11493                         case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
11494                         case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
11495                         case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
11496                         }
11497                         break;
11498                     }
11499                 } else {
11500                 do_itof:
11501     #if !defined(TCC_TARGET_ARM)
11502                     gen_cvt_itof1(dbt);
11503     #else
11504                     gen_cvt_itof(dbt);
11505     #endif
11506                 }
11507             } else if (sf) {
11508                 /* convert fp to int */
11509                 /* we handle char/short/etc... with generic code */
11510                 if (dbt != (VT_INT | VT_UNSIGNED) &&
11511                     dbt != (VT_LLONG | VT_UNSIGNED) &&
11512                     dbt != VT_LLONG)
11513                     dbt = VT_INT;
11514                 if (c) {
11515                     switch(dbt) {
11516                     case VT_LLONG | VT_UNSIGNED:
11517                     case VT_LLONG:
11518                         /* XXX: add const cases for long long */
11519                         goto do_ftoi;
11520                     case VT_INT | VT_UNSIGNED:
11521                         switch(sbt) {
11522                         case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
11523                         case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
11524                         case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
11525                         }
11526                         break;
11527                     default:
11528                         /* int case */
11529                         switch(sbt) {
11530                         case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
11531                         case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
11532                         case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
11533                         }
11534                         break;
11535                     }
11536                 } else {
11537                 do_ftoi:
11538                     gen_cvt_ftoi1(dbt);
11539                 }
11540                 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
11541                     /* additional cast for char/short/bool... */
11542                     vtop->type.t = dbt;
11543                     gen_cast(type);
11544                 }
11545             } else if ((dbt & VT_BTYPE) == VT_LLONG) {
11546                 if ((sbt & VT_BTYPE) != VT_LLONG) {
11547                     /* scalar to long long */
11548                     if (c) {
11549                         if (sbt == (VT_INT | VT_UNSIGNED))
11550                             vtop->c.ll = vtop->c.ui;
11551                         else
11552                             vtop->c.ll = vtop->c.i;
11553                     } else {
11554                         /* machine independent conversion */
11555                         gv(RC_INT);
11556                         /* generate high word */
11557                         if (sbt == (VT_INT | VT_UNSIGNED)) {
11558                             vpushi(0);
11559                             gv(RC_INT);
11560                         } else {
11561                             gv_dup();
11562                             vpushi(31);
11563                             gen_op(TOK_SAR);
11564                         }
11565                         /* patch second register */
11566                         vtop[-1].r2 = vtop->r;
11567                         vpop();
11568                     }
11569                 }
11570             } else if (dbt == VT_BOOL) {
11571                 /* scalar to bool */
11572                 vpushi(0);
11573                 gen_op(TOK_NE);
11574             } else if ((dbt & VT_BTYPE) == VT_BYTE || 
11575                        (dbt & VT_BTYPE) == VT_SHORT) {
11576                 force_charshort_cast(dbt);
11577             } else if ((dbt & VT_BTYPE) == VT_INT) {
11578                 /* scalar to int */
11579                 if (sbt == VT_LLONG) {
11580                     /* from long long: just take low order word */
11581                     lexpand();
11582                     vpop();
11583                 } 
11584                 /* if lvalue and single word type, nothing to do because
11585                    the lvalue already contains the real type size (see
11586                    VT_LVAL_xxx constants) */
11587             }
11588         }
11589         vtop->type = *type;
11590     }
11591     
11592     /* return type size. Put alignment at 'a' */
11593     static int type_size(CType *type, int *a)
11594     {
11595         Sym *s;
11596         int bt;
11597     
11598         bt = type->t & VT_BTYPE;
11599         if (bt == VT_STRUCT) {
11600             /* struct/union */
11601             s = type->ref;
11602             *a = s->r;
11603             return s->c;
11604         } else if (bt == VT_PTR) {
11605             if (type->t & VT_ARRAY) {
11606                 s = type->ref;
11607                 return type_size(&s->type, a) * s->c;
11608             } else {
11609                 *a = PTR_SIZE;
11610                 return PTR_SIZE;
11611             }
11612         } else if (bt == VT_LDOUBLE) {
11613             *a = LDOUBLE_ALIGN;
11614             return LDOUBLE_SIZE;
11615         } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
11616     #ifdef TCC_TARGET_I386
11617             *a = 4;
11618     #else
11619             *a = 8;
11620     #endif
11621             return 8;
11622         } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
11623             *a = 4;
11624             return 4;
11625         } else if (bt == VT_SHORT) {
11626             *a = 2;
11627             return 2;
11628         } else {
11629             /* char, void, function, _Bool */
11630             *a = 1;
11631             return 1;
11632         }
11633     }
11634     
11635     /* modify type so that its it is a pointer to type. */
11636     static void mk_pointer(CType *type)
11637     {
11638         Sym *s;
11639         s = sym_push(SYM_FIELD, type, 0, -1);
11640         type->t = VT_PTR | (type->t & ~VT_TYPE);
11641         type->ref = s;
11642     }
11643     
11644     /* compare function types. OLD functions match any new functions */
11645     static int is_compatible_func(CType *type1, CType *type2)
11646     {
11647         Sym *s1, *s2;
11648     
11649         s1 = type1->ref;
11650         s2 = type2->ref;
11651         if (!is_compatible_types(&s1->type, &s2->type))
11652             return 0;
11653         /* check func_call */
11654         if (s1->r != s2->r)
11655             return 0;
11656         /* XXX: not complete */
11657         if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
11658             return 1;
11659         if (s1->c != s2->c)
11660             return 0;
11661         while (s1 != NULL) {
11662             if (s2 == NULL)
11663                 return 0;
11664             if (!is_compatible_types(&s1->type, &s2->type))
11665                 return 0;
11666             s1 = s1->next;
11667             s2 = s2->next;
11668         }
11669         if (s2)
11670             return 0;
11671         return 1;
11672     }
11673     
11674     /* return true if type1 and type2 are exactly the same (including
11675        qualifiers). 
11676     
11677        - enums are not checked as gcc __builtin_types_compatible_p () 
11678      */
11679     static int is_compatible_types(CType *type1, CType *type2)
11680     {
11681         int bt1, t1, t2;
11682     
11683         t1 = type1->t & VT_TYPE;
11684         t2 = type2->t & VT_TYPE;
11685         /* XXX: bitfields ? */
11686         if (t1 != t2)
11687             return 0;
11688         /* test more complicated cases */
11689         bt1 = t1 & VT_BTYPE;
11690         if (bt1 == VT_PTR) {
11691             type1 = pointed_type(type1);
11692             type2 = pointed_type(type2);
11693             return is_compatible_types(type1, type2);
11694         } else if (bt1 == VT_STRUCT) {
11695             return (type1->ref == type2->ref);
11696         } else if (bt1 == VT_FUNC) {
11697             return is_compatible_func(type1, type2);
11698         } else {
11699             return 1;
11700         }
11701     }
11702     
11703     /* print a type. If 'varstr' is not NULL, then the variable is also
11704        printed in the type */
11705     /* XXX: union */
11706     /* XXX: add array and function pointers */
11707     void type_to_str(char *buf, int buf_size, 
11708                      CType *type, const char *varstr)
11709     {
11710         int bt, v, t;
11711         Sym *s, *sa;
11712         char buf1[256];
11713         const char *tstr;
11714     
11715         t = type->t & VT_TYPE;
11716         bt = t & VT_BTYPE;
11717         buf[0] = '\0';
11718         if (t & VT_CONSTANT)
11719             pstrcat(buf, buf_size, "const ");
11720         if (t & VT_VOLATILE)
11721             pstrcat(buf, buf_size, "volatile ");
11722         if (t & VT_UNSIGNED)
11723             pstrcat(buf, buf_size, "unsigned ");
11724         switch(bt) {
11725         case VT_VOID:
11726             tstr = "void";
11727             goto add_tstr;
11728         case VT_BOOL:
11729             tstr = "_Bool";
11730             goto add_tstr;
11731         case VT_BYTE:
11732             tstr = "char";
11733             goto add_tstr;
11734         case VT_SHORT:
11735             tstr = "short";
11736             goto add_tstr;
11737         case VT_INT:
11738             tstr = "int";
11739             goto add_tstr;
11740         case VT_LONG:
11741             tstr = "long";
11742             goto add_tstr;
11743         case VT_LLONG:
11744             tstr = "long long";
11745             goto add_tstr;
11746         case VT_FLOAT:
11747             tstr = "float";
11748             goto add_tstr;
11749         case VT_DOUBLE:
11750             tstr = "double";
11751             goto add_tstr;
11752         case VT_LDOUBLE:
11753             tstr = "long double";
11754         add_tstr:
11755             pstrcat(buf, buf_size, tstr);
11756             break;
11757         case VT_ENUM:
11758         case VT_STRUCT:
11759             if (bt == VT_STRUCT)
11760                 tstr = "struct ";
11761             else
11762                 tstr = "enum ";
11763             pstrcat(buf, buf_size, tstr);
11764             v = type->ref->v & ~SYM_STRUCT;
11765             if (v >= SYM_FIRST_ANOM)
11766                 pstrcat(buf, buf_size, "<anonymous>");
11767             else
11768                 pstrcat(buf, buf_size, get_tok_str(v, NULL));
11769             break;
11770         case VT_FUNC:
11771             s = type->ref;
11772             type_to_str(buf, buf_size, &s->type, varstr);
11773             pstrcat(buf, buf_size, "(");
11774             sa = s->next;
11775             while (sa != NULL) {
11776                 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
11777                 pstrcat(buf, buf_size, buf1);
11778                 sa = sa->next;
11779                 if (sa)
11780                     pstrcat(buf, buf_size, ", ");
11781             }
11782             pstrcat(buf, buf_size, ")");
11783             goto no_var;
11784         case VT_PTR:
11785             s = type->ref;
11786             pstrcpy(buf1, sizeof(buf1), "*");
11787             if (varstr)
11788                 pstrcat(buf1, sizeof(buf1), varstr);
11789             type_to_str(buf, buf_size, &s->type, buf1);
11790             goto no_var;
11791         }
11792         if (varstr) {
11793             pstrcat(buf, buf_size, " ");
11794             pstrcat(buf, buf_size, varstr);
11795         }
11796      no_var: ;
11797     }
11798     
11799     /* verify type compatibility to store vtop in 'dt' type, and generate
11800        casts if needed. */
11801     static void gen_assign_cast(CType *dt)
11802     {
11803         CType *st, *type1, *type2, tmp_type1, tmp_type2;
11804         char buf1[256], buf2[256];
11805         int dbt, sbt;
11806     
11807         st = &vtop->type; /* source type */
11808         dbt = dt->t & VT_BTYPE;
11809         sbt = st->t & VT_BTYPE;
11810         if (dt->t & VT_CONSTANT)
11811             warning("assignment of read-only location");
11812         switch(dbt) {
11813         case VT_PTR:
11814             /* special cases for pointers */
11815             /* '0' can also be a pointer */
11816             if (is_null_pointer(vtop))
11817                 goto type_ok;
11818             /* accept implicit pointer to integer cast with warning */
11819             if (is_integer_btype(sbt)) {
11820                 warning("assignment makes pointer from integer without a cast");
11821                 goto type_ok;
11822             }
11823             type1 = pointed_type(dt);
11824             /* a function is implicitely a function pointer */
11825             if (sbt == VT_FUNC) {
11826                 if ((type1->t & VT_BTYPE) != VT_VOID &&
11827                     !is_compatible_types(pointed_type(dt), st))
11828                     goto error;
11829                 else
11830                     goto type_ok;
11831             }
11832             if (sbt != VT_PTR)
11833                 goto error;
11834             type2 = pointed_type(st);
11835             if ((type1->t & VT_BTYPE) == VT_VOID || 
11836                 (type2->t & VT_BTYPE) == VT_VOID) {
11837                 /* void * can match anything */
11838             } else {
11839                 /* exact type match, except for unsigned */
11840                 tmp_type1 = *type1;
11841                 tmp_type2 = *type2;
11842                 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
11843                 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
11844                 if (!is_compatible_types(&tmp_type1, &tmp_type2))
11845                     goto error;
11846             }
11847             /* check const and volatile */
11848             if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
11849                 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
11850                 warning("assignment discards qualifiers from pointer target type");
11851             break;
11852         case VT_BYTE:
11853         case VT_SHORT:
11854         case VT_INT:
11855         case VT_LLONG:
11856             if (sbt == VT_PTR || sbt == VT_FUNC) {
11857                 warning("assignment makes integer from pointer without a cast");
11858             }
11859             /* XXX: more tests */
11860             break;
11861         case VT_STRUCT:
11862             tmp_type1 = *dt;
11863             tmp_type2 = *st;
11864             tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
11865             tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
11866             if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
11867             error:
11868                 type_to_str(buf1, sizeof(buf1), st, NULL);
11869                 type_to_str(buf2, sizeof(buf2), dt, NULL);
11870                 error("cannot cast '%s' to '%s'", buf1, buf2);
11871             }
11872             break;
11873         }
11874      type_ok:
11875         gen_cast(dt);
11876     }
11877     
11878     /* store vtop in lvalue pushed on stack */
11879     void vstore(void)
11880     {
11881         int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
11882     
11883         ft = vtop[-1].type.t;
11884         sbt = vtop->type.t & VT_BTYPE;
11885         dbt = ft & VT_BTYPE;
11886         if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
11887             (sbt == VT_INT && dbt == VT_SHORT)) {
11888             /* optimize char/short casts */
11889             delayed_cast = VT_MUSTCAST;
11890             vtop->type.t = ft & VT_TYPE;
11891             /* XXX: factorize */
11892             if (ft & VT_CONSTANT)
11893                 warning("assignment of read-only location");
11894         } else {
11895             delayed_cast = 0;
11896             if (!(ft & VT_BITFIELD))
11897                 gen_assign_cast(&vtop[-1].type);
11898         }
11899     
11900         if (sbt == VT_STRUCT) {
11901             /* if structure, only generate pointer */
11902             /* structure assignment : generate memcpy */
11903             /* XXX: optimize if small size */
11904             if (!nocode_wanted) {
11905                 size = type_size(&vtop->type, &align);
11906     
11907                 vpush_global_sym(&func_old_type, TOK_memcpy);
11908     
11909                 /* destination */
11910                 vpushv(vtop - 2);
11911                 vtop->type.t = VT_INT;
11912                 gaddrof();
11913                 /* source */
11914                 vpushv(vtop - 2);
11915                 vtop->type.t = VT_INT;
11916                 gaddrof();
11917                 /* type size */
11918                 vpushi(size);
11919                 gfunc_call(3);
11920                 
11921                 vswap();
11922                 vpop();
11923             } else {
11924                 vswap();
11925                 vpop();
11926             }
11927             /* leave source on stack */
11928         } else if (ft & VT_BITFIELD) {
11929             /* bitfield store handling */
11930             bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
11931             bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
11932             /* remove bit field info to avoid loops */
11933             vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
11934     
11935             /* duplicate destination */
11936             vdup();
11937             vtop[-1] = vtop[-2];
11938     
11939             /* mask and shift source */
11940             vpushi((1 << bit_size) - 1);
11941             gen_op('&');
11942             vpushi(bit_pos);
11943             gen_op(TOK_SHL);
11944             /* load destination, mask and or with source */
11945             vswap();
11946             vpushi(~(((1 << bit_size) - 1) << bit_pos));
11947             gen_op('&');
11948             gen_op('|');
11949             /* store result */
11950             vstore();
11951         } else {
11952     #ifdef CONFIG_TCC_BCHECK
11953             /* bound check case */
11954             if (vtop[-1].r & VT_MUSTBOUND) {
11955                 vswap();
11956                 gbound();
11957                 vswap();
11958             }
11959     #endif
11960             if (!nocode_wanted) {
11961                 rc = RC_INT;
11962                 if (is_float(ft))
11963                     rc = RC_FLOAT;
11964                 r = gv(rc);  /* generate value */
11965                 /* if lvalue was saved on stack, must read it */
11966                 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
11967                     SValue sv;
11968                     t = get_reg(RC_INT);
11969                     sv.type.t = VT_INT;
11970                     sv.r = VT_LOCAL | VT_LVAL;
11971                     sv.c.ul = vtop[-1].c.ul;
11972                     load(t, &sv);
11973                     vtop[-1].r = t | VT_LVAL;
11974                 }
11975                 store(r, vtop - 1);
11976                 /* two word case handling : store second register at word + 4 */
11977                 if ((ft & VT_BTYPE) == VT_LLONG) {
11978                     vswap();
11979                     /* convert to int to increment easily */
11980                     vtop->type.t = VT_INT;
11981                     gaddrof();
11982                     vpushi(4);
11983                     gen_op('+');
11984                     vtop->r |= VT_LVAL;
11985                     vswap();
11986                     /* XXX: it works because r2 is spilled last ! */
11987                     store(vtop->r2, vtop - 1);
11988                 }
11989             }
11990             vswap();
11991             vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
11992             vtop->r |= delayed_cast;
11993         }
11994     }
11995     
11996     /* post defines POST/PRE add. c is the token ++ or -- */
11997     void inc(int post, int c)
11998     {
11999         test_lvalue();
12000         vdup(); /* save lvalue */
12001         if (post) {
12002             gv_dup(); /* duplicate value */
12003             vrotb(3);
12004             vrotb(3);
12005         }
12006         /* add constant */
12007         vpushi(c - TOK_MID); 
12008         gen_op('+');
12009         vstore(); /* store value */
12010         if (post)
12011             vpop(); /* if post op, return saved value */
12012     }
12013     
12014     /* Parse GNUC __attribute__ extension. Currently, the following
12015        extensions are recognized:
12016        - aligned(n) : set data/function alignment.
12017        - packed : force data alignment to 1
12018        - section(x) : generate data/code in this section.
12019        - unused : currently ignored, but may be used someday.
12020        - regparm(n) : pass function parameters in registers (i386 only)
12021      */
12022     static void parse_attribute(AttributeDef *ad)
12023     {
12024         int t, n;
12025         
12026         while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
12027         next();
12028         skip('(');
12029         skip('(');
12030         while (tok != ')') {
12031             if (tok < TOK_IDENT)
12032                 expect("attribute name");
12033             t = tok;
12034             next();
12035             switch(t) {
12036             case TOK_SECTION1:
12037             case TOK_SECTION2:
12038                 skip('(');
12039                 if (tok != TOK_STR)
12040                     expect("section name");
12041                 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
12042                 next();
12043                 skip(')');
12044                 break;
12045             case TOK_ALIGNED1:
12046             case TOK_ALIGNED2:
12047                 if (tok == '(') {
12048                     next();
12049                     n = expr_const();
12050                     if (n <= 0 || (n & (n - 1)) != 0) 
12051                         error("alignment must be a positive power of two");
12052                     skip(')');
12053                 } else {
12054                     n = MAX_ALIGN;
12055                 }
12056                 ad->aligned = n;
12057                 break;
12058             case TOK_PACKED1:
12059             case TOK_PACKED2:
12060                 ad->packed = 1;
12061                 break;
12062             case TOK_UNUSED1:
12063             case TOK_UNUSED2:
12064                 /* currently, no need to handle it because tcc does not
12065                    track unused objects */
12066                 break;
12067             case TOK_NORETURN1:
12068             case TOK_NORETURN2:
12069                 /* currently, no need to handle it because tcc does not
12070                    track unused objects */
12071                 break;
12072             case TOK_CDECL1:
12073             case TOK_CDECL2:
12074             case TOK_CDECL3:
12075                 ad->func_call = FUNC_CDECL;
12076                 break;
12077             case TOK_STDCALL1:
12078             case TOK_STDCALL2:
12079             case TOK_STDCALL3:
12080                 ad->func_call = FUNC_STDCALL;
12081                 break;
12082     #ifdef TCC_TARGET_I386
12083             case TOK_REGPARM1:
12084             case TOK_REGPARM2:
12085                 skip('(');
12086                 n = expr_const();
12087                 if (n > 3) 
12088                     n = 3;
12089                 else if (n < 0)
12090                     n = 0;
12091                 if (n > 0)
12092                     ad->func_call = FUNC_FASTCALL1 + n - 1;
12093                 skip(')');
12094                 break;
12095     #endif
12096             case TOK_DLLEXPORT:
12097                 ad->dllexport = 1;
12098                 break;
12099             default:
12100                 if (tcc_state->warn_unsupported)
12101                     warning("'%s' attribute ignored", get_tok_str(t, NULL));
12102                 /* skip parameters */
12103                 /* XXX: skip parenthesis too */
12104                 if (tok == '(') {
12105                     next();
12106                     while (tok != ')' && tok != -1)
12107                         next();
12108                     next();
12109                 }
12110                 break;
12111             }
12112             if (tok != ',')
12113                 break;
12114             next();
12115         }
12116         skip(')');
12117         skip(')');
12118         }
12119     }
12120     
12121     /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
12122     static void struct_decl(CType *type, int u)
12123     {
12124         int a, v, size, align, maxalign, c, offset;
12125         int bit_size, bit_pos, bsize, bt, lbit_pos;
12126         Sym *s, *ss, **ps;
12127         AttributeDef ad;
12128         CType type1, btype;
12129     
12130         a = tok; /* save decl type */
12131         next();
12132         if (tok != '{') {
12133             v = tok;
12134             next();
12135             /* struct already defined ? return it */
12136             if (v < TOK_IDENT)
12137                 expect("struct/union/enum name");
12138             s = struct_find(v);
12139             if (s) {
12140                 if (s->type.t != a)
12141                     error("invalid type");
12142                 goto do_decl;
12143             }
12144         } else {
12145             v = anon_sym++;
12146         }
12147         type1.t = a;
12148         /* we put an undefined size for struct/union */
12149         s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
12150         s->r = 0; /* default alignment is zero as gcc */
12151         /* put struct/union/enum name in type */
12152      do_decl:
12153         type->t = u;
12154         type->ref = s;
12155         
12156         if (tok == '{') {
12157             next();
12158             if (s->c != -1)
12159                 error("struct/union/enum already defined");
12160             /* cannot be empty */
12161             c = 0;
12162             /* non empty enums are not allowed */
12163             if (a == TOK_ENUM) {
12164                 for(;;) {
12165                     v = tok;
12166                     if (v < TOK_UIDENT)
12167                         expect("identifier");
12168                     next();
12169                     if (tok == '=') {
12170                         next();
12171                         c = expr_const();
12172                     }
12173                     /* enum symbols have static storage */
12174                     ss = sym_push(v, &int_type, VT_CONST, c);
12175                     ss->type.t |= VT_STATIC;
12176                     if (tok != ',')
12177                         break;
12178                     next();
12179                     c++;
12180                     /* NOTE: we accept a trailing comma */
12181                     if (tok == '}')
12182                         break;
12183                 }
12184                 skip('}');
12185             } else {
12186                 maxalign = 1;
12187                 ps = &s->next;
12188                 bit_pos = 0;
12189                 offset = 0;
12190                 while (tok != '}') {
12191                     parse_btype(&btype, &ad);
12192                     while (1) {
12193                         bit_size = -1;
12194                         v = 0;
12195                         type1 = btype;
12196                         if (tok != ':') {
12197                             type_decl(&type1, &ad, &v, TYPE_DIRECT);
12198                             if ((type1.t & VT_BTYPE) == VT_FUNC ||
12199                                 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
12200                                 error("invalid type for '%s'", 
12201                                       get_tok_str(v, NULL));
12202                         }
12203                         if (tok == ':') {
12204                             next();
12205                             bit_size = expr_const();
12206                             /* XXX: handle v = 0 case for messages */
12207                             if (bit_size < 0)
12208                                 error("negative width in bit-field '%s'", 
12209                                       get_tok_str(v, NULL));
12210                             if (v && bit_size == 0)
12211                                 error("zero width for bit-field '%s'", 
12212                                       get_tok_str(v, NULL));
12213                         }
12214                         size = type_size(&type1, &align);
12215                         if (ad.aligned) {
12216                             if (align < ad.aligned)
12217                                 align = ad.aligned;
12218                         } else if (ad.packed) {
12219                             align = 1;
12220                         } else if (*tcc_state->pack_stack_ptr) {
12221                             if (align > *tcc_state->pack_stack_ptr)
12222                                 align = *tcc_state->pack_stack_ptr;
12223                         }
12224                         lbit_pos = 0;
12225                         if (bit_size >= 0) {
12226                             bt = type1.t & VT_BTYPE;
12227                             if (bt != VT_INT && 
12228                                 bt != VT_BYTE && 
12229                                 bt != VT_SHORT &&
12230                                 bt != VT_BOOL &&
12231                                 bt != VT_ENUM)
12232                                 error("bitfields must have scalar type");
12233                             bsize = size * 8;
12234                             if (bit_size > bsize) {
12235                                 error("width of '%s' exceeds its type",
12236                                       get_tok_str(v, NULL));
12237                             } else if (bit_size == bsize) {
12238                                 /* no need for bit fields */
12239                                 bit_pos = 0;
12240                             } else if (bit_size == 0) {
12241                                 /* XXX: what to do if only padding in a
12242                                    structure ? */
12243                                 /* zero size: means to pad */
12244                                 if (bit_pos > 0)
12245                                     bit_pos = bsize;
12246                             } else {
12247                                 /* we do not have enough room ? */
12248                                 if ((bit_pos + bit_size) > bsize)
12249                                     bit_pos = 0;
12250                                 lbit_pos = bit_pos;
12251                                 /* XXX: handle LSB first */
12252                                 type1.t |= VT_BITFIELD | 
12253                                     (bit_pos << VT_STRUCT_SHIFT) |
12254                                     (bit_size << (VT_STRUCT_SHIFT + 6));
12255                                 bit_pos += bit_size;
12256                             }
12257                         } else {
12258                             bit_pos = 0;
12259                         }
12260                         if (v) {
12261                             /* add new memory data only if starting
12262                                bit field */
12263                             if (lbit_pos == 0) {
12264                                 if (a == TOK_STRUCT) {
12265                                     c = (c + align - 1) & -align;
12266                                     offset = c;
12267                                     c += size;
12268                                 } else {
12269                                     offset = 0;
12270                                     if (size > c)
12271                                         c = size;
12272                                 }
12273                                 if (align > maxalign)
12274                                     maxalign = align;
12275                             }
12276     #if 0
12277                             printf("add field %s offset=%d", 
12278                                    get_tok_str(v, NULL), offset);
12279                             if (type1.t & VT_BITFIELD) {
12280                                 printf(" pos=%d size=%d", 
12281                                        (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
12282                                        (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
12283                             }
12284                             printf("\n");
12285     #endif
12286                             ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
12287                             *ps = ss;
12288                             ps = &ss->next;
12289                         }
12290                         if (tok == ';' || tok == TOK_EOF)
12291                             break;
12292                         skip(',');
12293                     }
12294                     skip(';');
12295                 }
12296                 skip('}');
12297                 /* store size and alignment */
12298                 s->c = (c + maxalign - 1) & -maxalign; 
12299                 s->r = maxalign;
12300             }
12301         }
12302     }
12303     
12304     /* return 0 if no type declaration. otherwise, return the basic type
12305        and skip it. 
12306      */
12307     static int parse_btype(CType *type, AttributeDef *ad)
12308     {
12309         int t, u, type_found, typespec_found;
12310         Sym *s;
12311         CType type1;
12312     
12313         memset(ad, 0, sizeof(AttributeDef));
12314         type_found = 0;
12315         typespec_found = 0;
12316         t = 0;
12317         while(1) {
12318             switch(tok) {
12319             case TOK_EXTENSION:
12320                 /* currently, we really ignore extension */
12321                 next();
12322                 continue;
12323     
12324                 /* basic types */
12325             case TOK_CHAR:
12326                 u = VT_BYTE;
12327             basic_type:
12328                 next();
12329             basic_type1:
12330                 if ((t & VT_BTYPE) != 0)
12331                     error("too many basic types");
12332                 t |= u;
12333                 typespec_found = 1;
12334                 break;
12335             case TOK_VOID:
12336                 u = VT_VOID;
12337                 goto basic_type;
12338             case TOK_SHORT:
12339                 u = VT_SHORT;
12340                 goto basic_type;
12341             case TOK_INT:
12342                 next();
12343                 typespec_found = 1;
12344                 break;
12345             case TOK_LONG:
12346                 next();
12347                 if ((t & VT_BTYPE) == VT_DOUBLE) {
12348                     t = (t & ~VT_BTYPE) | VT_LDOUBLE;
12349                 } else if ((t & VT_BTYPE) == VT_LONG) {
12350                     t = (t & ~VT_BTYPE) | VT_LLONG;
12351                 } else {
12352                     u = VT_LONG;
12353                     goto basic_type1;
12354                 }
12355                 break;
12356             case TOK_BOOL:
12357                 u = VT_BOOL;
12358                 goto basic_type;
12359             case TOK_FLOAT:
12360                 u = VT_FLOAT;
12361                 goto basic_type;
12362             case TOK_DOUBLE:
12363                 next();
12364                 if ((t & VT_BTYPE) == VT_LONG) {
12365                     t = (t & ~VT_BTYPE) | VT_LDOUBLE;
12366                 } else {
12367                     u = VT_DOUBLE;
12368                     goto basic_type1;
12369                 }
12370                 break;
12371             case TOK_ENUM:
12372                 struct_decl(&type1, VT_ENUM);
12373             basic_type2:
12374                 u = type1.t;
12375                 type->ref = type1.ref;
12376                 goto basic_type1;
12377             case TOK_STRUCT:
12378             case TOK_UNION:
12379                 struct_decl(&type1, VT_STRUCT);
12380                 goto basic_type2;
12381     
12382                 /* type modifiers */
12383             case TOK_CONST1:
12384             case TOK_CONST2:
12385             case TOK_CONST3:
12386                 t |= VT_CONSTANT;
12387                 next();
12388                 break;
12389             case TOK_VOLATILE1:
12390             case TOK_VOLATILE2:
12391             case TOK_VOLATILE3:
12392                 t |= VT_VOLATILE;
12393                 next();
12394                 break;
12395             case TOK_SIGNED1:
12396             case TOK_SIGNED2:
12397             case TOK_SIGNED3:
12398                 typespec_found = 1;
12399     	    t |= VT_SIGNED;
12400     	    next();
12401     	    break;
12402             case TOK_REGISTER:
12403             case TOK_AUTO:
12404             case TOK_RESTRICT1:
12405             case TOK_RESTRICT2:
12406             case TOK_RESTRICT3:
12407                 next();
12408                 break;
12409             case TOK_UNSIGNED:
12410                 t |= VT_UNSIGNED;
12411                 next();
12412                 typespec_found = 1;
12413                 break;
12414     
12415                 /* storage */
12416             case TOK_EXTERN:
12417                 t |= VT_EXTERN;
12418                 next();
12419                 break;
12420             case TOK_STATIC:
12421                 t |= VT_STATIC;
12422                 next();
12423                 break;
12424             case TOK_TYPEDEF:
12425                 t |= VT_TYPEDEF;
12426                 next();
12427                 break;
12428             case TOK_INLINE1:
12429             case TOK_INLINE2:
12430             case TOK_INLINE3:
12431                 t |= VT_INLINE;
12432                 next();
12433                 break;
12434     
12435                 /* GNUC attribute */
12436             case TOK_ATTRIBUTE1:
12437             case TOK_ATTRIBUTE2:
12438                 parse_attribute(ad);
12439                 break;
12440                 /* GNUC typeof */
12441             case TOK_TYPEOF1:
12442             case TOK_TYPEOF2:
12443             case TOK_TYPEOF3:
12444                 next();
12445                 parse_expr_type(&type1);
12446                 goto basic_type2;
12447             default:
12448                 if (typespec_found)
12449                     goto the_end;
12450                 s = sym_find(tok);
12451                 if (!s || !(s->type.t & VT_TYPEDEF))
12452                     goto the_end;
12453                 t |= (s->type.t & ~VT_TYPEDEF);
12454                 type->ref = s->type.ref;
12455                 next();
12456                 break;
12457             }
12458             type_found = 1;
12459         }
12460     the_end:
12461         if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
12462           error("signed and unsigned modifier");
12463         if (tcc_state->char_is_unsigned) {
12464             if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
12465                 t |= VT_UNSIGNED;
12466         }
12467         t &= ~VT_SIGNED;
12468     
12469         /* long is never used as type */
12470         if ((t & VT_BTYPE) == VT_LONG)
12471             t = (t & ~VT_BTYPE) | VT_INT;
12472         type->t = t;
12473         return type_found;
12474     }
12475     
12476     /* convert a function parameter type (array to pointer and function to
12477        function pointer) */
12478     static inline void convert_parameter_type(CType *pt)
12479     {
12480         /* remove const and volatile qualifiers (XXX: const could be used
12481            to indicate a const function parameter */
12482         pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
12483         /* array must be transformed to pointer according to ANSI C */
12484         pt->t &= ~VT_ARRAY;
12485         if ((pt->t & VT_BTYPE) == VT_FUNC) {
12486             mk_pointer(pt);
12487         }
12488     }
12489     
12490     static void post_type(CType *type, AttributeDef *ad)
12491     {
12492         int n, l, t1;
12493         Sym **plast, *s, *first;
12494         AttributeDef ad1;
12495         CType pt;
12496     
12497         if (tok == '(') {
12498             /* function declaration */
12499             next();
12500             l = 0;
12501             first = NULL;
12502             plast = &first;
12503             while (tok != ')') {
12504                 /* read param name and compute offset */
12505                 if (l != FUNC_OLD) {
12506                     if (!parse_btype(&pt, &ad1)) {
12507                         if (l) {
12508                             error("invalid type");
12509                         } else {
12510                             l = FUNC_OLD;
12511                             goto old_proto;
12512                         }
12513                     }
12514                     l = FUNC_NEW;
12515                     if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
12516                         break;
12517                     type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
12518                     if ((pt.t & VT_BTYPE) == VT_VOID)
12519                         error("parameter declared as void");
12520                 } else {
12521                 old_proto:
12522                     n = tok;
12523                     pt.t = VT_INT;
12524                     next();
12525                 }
12526                 convert_parameter_type(&pt);
12527                 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
12528                 *plast = s;
12529                 plast = &s->next;
12530                 if (tok == ',') {
12531                     next();
12532                     if (l == FUNC_NEW && tok == TOK_DOTS) {
12533                         l = FUNC_ELLIPSIS;
12534                         next();
12535                         break;
12536                     }
12537                 }
12538             }
12539             /* if no parameters, then old type prototype */
12540             if (l == 0)
12541                 l = FUNC_OLD;
12542             skip(')');
12543             t1 = type->t & VT_STORAGE;
12544             /* NOTE: const is ignored in returned type as it has a special
12545                meaning in gcc / C++ */
12546             type->t &= ~(VT_STORAGE | VT_CONSTANT); 
12547             post_type(type, ad);
12548             /* we push a anonymous symbol which will contain the function prototype */
12549             s = sym_push(SYM_FIELD, type, ad->func_call, l);
12550             s->next = first;
12551             type->t = t1 | VT_FUNC;
12552             type->ref = s;
12553         } else if (tok == '[') {
12554             /* array definition */
12555             next();
12556             n = -1;
12557             if (tok != ']') {
12558                 n = expr_const();
12559                 if (n < 0)
12560                     error("invalid array size");    
12561             }
12562             skip(']');
12563             /* parse next post type */
12564             t1 = type->t & VT_STORAGE;
12565             type->t &= ~VT_STORAGE;
12566             post_type(type, ad);
12567             
12568             /* we push a anonymous symbol which will contain the array
12569                element type */
12570             s = sym_push(SYM_FIELD, type, 0, n);
12571             type->t = t1 | VT_ARRAY | VT_PTR;
12572             type->ref = s;
12573         }
12574     }
12575     
12576     /* Parse a type declaration (except basic type), and return the type
12577        in 'type'. 'td' is a bitmask indicating which kind of type decl is
12578        expected. 'type' should contain the basic type. 'ad' is the
12579        attribute definition of the basic type. It can be modified by
12580        type_decl(). 
12581      */
12582     static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
12583     {
12584         Sym *s;
12585         CType type1, *type2;
12586         int qualifiers;
12587         
12588         while (tok == '*') {
12589             qualifiers = 0;
12590         redo:
12591             next();
12592             switch(tok) {
12593             case TOK_CONST1:
12594             case TOK_CONST2:
12595             case TOK_CONST3:
12596                 qualifiers |= VT_CONSTANT;
12597                 goto redo;
12598             case TOK_VOLATILE1:
12599             case TOK_VOLATILE2:
12600             case TOK_VOLATILE3:
12601                 qualifiers |= VT_VOLATILE;
12602                 goto redo;
12603             case TOK_RESTRICT1:
12604             case TOK_RESTRICT2:
12605             case TOK_RESTRICT3:
12606                 goto redo;
12607             }
12608             mk_pointer(type);
12609             type->t |= qualifiers;
12610         }
12611         
12612         /* XXX: clarify attribute handling */
12613         if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
12614             parse_attribute(ad);
12615     
12616         /* recursive type */
12617         /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
12618         type1.t = 0; /* XXX: same as int */
12619         if (tok == '(') {
12620             next();
12621             /* XXX: this is not correct to modify 'ad' at this point, but
12622                the syntax is not clear */
12623             if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
12624                 parse_attribute(ad);
12625             type_decl(&type1, ad, v, td);
12626             skip(')');
12627         } else {
12628             /* type identifier */
12629             if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
12630                 *v = tok;
12631                 next();
12632             } else {
12633                 if (!(td & TYPE_ABSTRACT))
12634                     expect("identifier");
12635                 *v = 0;
12636             }
12637         }
12638         post_type(type, ad);
12639         if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
12640             parse_attribute(ad);
12641         if (!type1.t)
12642             return;
12643         /* append type at the end of type1 */
12644         type2 = &type1;
12645         for(;;) {
12646             s = type2->ref;
12647             type2 = &s->type;
12648             if (!type2->t) {
12649                 *type2 = *type;
12650                 break;
12651             }
12652         }
12653         *type = type1;
12654     }
12655     
12656     /* compute the lvalue VT_LVAL_xxx needed to match type t. */
12657     static int lvalue_type(int t)
12658     {
12659         int bt, r;
12660         r = VT_LVAL;
12661         bt = t & VT_BTYPE;
12662         if (bt == VT_BYTE || bt == VT_BOOL)
12663             r |= VT_LVAL_BYTE;
12664         else if (bt == VT_SHORT)
12665             r |= VT_LVAL_SHORT;
12666         else
12667             return r;
12668         if (t & VT_UNSIGNED)
12669             r |= VT_LVAL_UNSIGNED;
12670         return r;
12671     }
12672     
12673     /* indirection with full error checking and bound check */
12674     static void indir(void)
12675     {
12676         if ((vtop->type.t & VT_BTYPE) != VT_PTR)
12677             expect("pointer");
12678         if ((vtop->r & VT_LVAL) && !nocode_wanted)
12679             gv(RC_INT);
12680         vtop->type = *pointed_type(&vtop->type);
12681         /* an array is never an lvalue */
12682         if (!(vtop->type.t & VT_ARRAY)) {
12683             vtop->r |= lvalue_type(vtop->type.t);
12684             /* if bound checking, the referenced pointer must be checked */
12685             if (do_bounds_check) 
12686                 vtop->r |= VT_MUSTBOUND;
12687         }
12688     }
12689     
12690     /* pass a parameter to a function and do type checking and casting */
12691     static void gfunc_param_typed(Sym *func, Sym *arg)
12692     {
12693         int func_type;
12694         CType type;
12695     
12696         func_type = func->c;
12697         if (func_type == FUNC_OLD ||
12698             (func_type == FUNC_ELLIPSIS && arg == NULL)) {
12699             /* default casting : only need to convert float to double */
12700             if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
12701                 type.t = VT_DOUBLE;
12702                 gen_cast(&type);
12703             }
12704         } else if (arg == NULL) {
12705             error("too many arguments to function");
12706         } else {
12707             type = arg->type;
12708             type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
12709             gen_assign_cast(&type);
12710         }
12711     }
12712     
12713     /* parse an expression of the form '(type)' or '(expr)' and return its
12714        type */
12715     static void parse_expr_type(CType *type)
12716     {
12717         int n;
12718         AttributeDef ad;
12719     
12720         skip('(');
12721         if (parse_btype(type, &ad)) {
12722             type_decl(type, &ad, &n, TYPE_ABSTRACT);
12723         } else {
12724             expr_type(type);
12725         }
12726         skip(')');
12727     }
12728     
12729     static void parse_type(CType *type)
12730     {
12731         AttributeDef ad;
12732         int n;
12733     
12734         if (!parse_btype(type, &ad)) {
12735             expect("type");
12736         }
12737         type_decl(type, &ad, &n, TYPE_ABSTRACT);
12738     }
12739     
12740     static void vpush_tokc(int t)
12741     {
12742         CType type;
12743         type.t = t;
12744         vsetc(&type, VT_CONST, &tokc);
12745     }
12746     
12747     static void unary(void)
12748     {
12749         int n, t, align, size, r;
12750         CType type;
12751         Sym *s;
12752         AttributeDef ad;
12753     
12754         /* XXX: GCC 2.95.3 does not generate a table although it should be
12755            better here */
12756      tok_next:
12757         switch(tok) {
12758         case TOK_EXTENSION:
12759             next();
12760             goto tok_next;
12761         case TOK_CINT:
12762         case TOK_CCHAR: 
12763         case TOK_LCHAR:
12764             vpushi(tokc.i);
12765             next();
12766             break;
12767         case TOK_CUINT:
12768             vpush_tokc(VT_INT | VT_UNSIGNED);
12769             next();
12770             break;
12771         case TOK_CLLONG:
12772             vpush_tokc(VT_LLONG);
12773             next();
12774             break;
12775         case TOK_CULLONG:
12776             vpush_tokc(VT_LLONG | VT_UNSIGNED);
12777             next();
12778             break;
12779         case TOK_CFLOAT:
12780             vpush_tokc(VT_FLOAT);
12781             next();
12782             break;
12783         case TOK_CDOUBLE:
12784             vpush_tokc(VT_DOUBLE);
12785             next();
12786             break;
12787         case TOK_CLDOUBLE:
12788             vpush_tokc(VT_LDOUBLE);
12789             next();
12790             break;
12791         case TOK___FUNCTION__:
12792             if (!gnu_ext)
12793                 goto tok_identifier;
12794             /* fall thru */
12795         case TOK___FUNC__:
12796             {
12797                 void *ptr;
12798                 int len;
12799                 /* special function name identifier */
12800                 len = strlen(funcname) + 1;
12801                 /* generate char[len] type */
12802                 type.t = VT_BYTE;
12803                 mk_pointer(&type);
12804                 type.t |= VT_ARRAY;
12805                 type.ref->c = len;
12806                 vpush_ref(&type, data_section, data_section->data_offset, len);
12807                 ptr = section_ptr_add(data_section, len);
12808                 memcpy(ptr, funcname, len);
12809                 next();
12810             }
12811             break;
12812         case TOK_LSTR:
12813             t = VT_INT;
12814             goto str_init;
12815         case TOK_STR:
12816             /* string parsing */
12817             t = VT_BYTE;
12818         str_init:
12819             if (tcc_state->warn_write_strings)
12820                 t |= VT_CONSTANT;
12821             type.t = t;
12822             mk_pointer(&type);
12823             type.t |= VT_ARRAY;
12824             memset(&ad, 0, sizeof(AttributeDef));
12825             decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
12826             break;
12827         case '(':
12828             next();
12829             /* cast ? */
12830             if (parse_btype(&type, &ad)) {
12831                 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
12832                 skip(')');
12833                 /* check ISOC99 compound literal */
12834                 if (tok == '{') {
12835                         /* data is allocated locally by default */
12836                     if (global_expr)
12837                         r = VT_CONST;
12838                     else
12839                         r = VT_LOCAL;
12840                     /* all except arrays are lvalues */
12841                     if (!(type.t & VT_ARRAY))
12842                         r |= lvalue_type(type.t);
12843                     memset(&ad, 0, sizeof(AttributeDef));
12844                     decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
12845                 } else {
12846                     unary();
12847                     gen_cast(&type);
12848                 }
12849             } else if (tok == '{') {
12850                 /* save all registers */
12851                 save_regs(0); 
12852                 /* statement expression : we do not accept break/continue
12853                    inside as GCC does */
12854                 block(NULL, NULL, NULL, NULL, 0, 1);
12855                 skip(')');
12856             } else {
12857                 gexpr();
12858                 skip(')');
12859             }
12860             break;
12861         case '*':
12862             next();
12863             unary();
12864             indir();
12865             break;
12866         case '&':
12867             next();
12868             unary();
12869             /* functions names must be treated as function pointers,
12870                except for unary '&' and sizeof. Since we consider that
12871                functions are not lvalues, we only have to handle it
12872                there and in function calls. */
12873             /* arrays can also be used although they are not lvalues */
12874             if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
12875                 !(vtop->type.t & VT_ARRAY))
12876                 test_lvalue();
12877             mk_pointer(&vtop->type);
12878             gaddrof();
12879             break;
12880         case '!':
12881             next();
12882             unary();
12883             if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST)
12884                 vtop->c.i = !vtop->c.i;
12885             else if ((vtop->r & VT_VALMASK) == VT_CMP)
12886                 vtop->c.i = vtop->c.i ^ 1;
12887             else
12888                 vseti(VT_JMP, gtst(1, 0));
12889             break;
12890         case '~':
12891             next();
12892             unary();
12893             vpushi(-1);
12894             gen_op('^');
12895             break;
12896         case '+':
12897             next();
12898             /* in order to force cast, we add zero */
12899             unary();
12900             if ((vtop->type.t & VT_BTYPE) == VT_PTR)
12901                 error("pointer not accepted for unary plus");
12902             vpushi(0);
12903             gen_op('+');
12904             break;
12905         case TOK_SIZEOF:
12906         case TOK_ALIGNOF1:
12907         case TOK_ALIGNOF2:
12908             t = tok;
12909             next();
12910             if (tok == '(') {
12911                 parse_expr_type(&type);
12912             } else {
12913                 unary_type(&type);
12914             }
12915             size = type_size(&type, &align);
12916             if (t == TOK_SIZEOF) {
12917                 if (size < 0)
12918                     error("sizeof applied to an incomplete type");
12919                 vpushi(size);
12920             } else {
12921                 vpushi(align);
12922             }
12923             break;
12924     
12925         case TOK_builtin_types_compatible_p:
12926             {
12927                 CType type1, type2;
12928                 next();
12929                 skip('(');
12930                 parse_type(&type1);
12931                 skip(',');
12932                 parse_type(&type2);
12933                 skip(')');
12934                 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
12935                 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
12936                 vpushi(is_compatible_types(&type1, &type2));
12937             }
12938             break;
12939         case TOK_builtin_constant_p:
12940             {
12941                 int saved_nocode_wanted, res;
12942                 next();
12943                 skip('(');
12944                 saved_nocode_wanted = nocode_wanted;
12945                 nocode_wanted = 1;
12946                 gexpr();
12947                 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
12948                 vpop();
12949                 nocode_wanted = saved_nocode_wanted;
12950                 skip(')');
12951                 vpushi(res);
12952             }
12953             break;
12954         case TOK_INC:
12955         case TOK_DEC:
12956             t = tok;
12957             next();
12958             unary();
12959             inc(0, t);
12960             break;
12961         case '-':
12962             next();
12963             vpushi(0);
12964             unary();
12965             gen_op('-');
12966             break;
12967         case TOK_LAND:
12968             if (!gnu_ext)
12969                 goto tok_identifier;
12970             next();
12971             /* allow to take the address of a label */
12972             if (tok < TOK_UIDENT)
12973                 expect("label identifier");
12974             s = label_find(tok);
12975             if (!s) {
12976                 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
12977             } else {
12978                 if (s->r == LABEL_DECLARED)
12979                     s->r = LABEL_FORWARD;
12980             }
12981             if (!s->type.t) {
12982                 s->type.t = VT_VOID;
12983                 mk_pointer(&s->type);
12984                 s->type.t |= VT_STATIC;
12985             }
12986             vset(&s->type, VT_CONST | VT_SYM, 0);
12987             vtop->sym = s;
12988             next();
12989             break;
12990         default:
12991         tok_identifier:
12992             t = tok;
12993             next();
12994             if (t < TOK_UIDENT)
12995                 expect("identifier");
12996             s = sym_find(t);
12997             if (!s) {
12998                 if (tok != '(')
12999                     error("'%s' undeclared", get_tok_str(t, NULL));
13000                 /* for simple function calls, we tolerate undeclared
13001                    external reference to int() function */
13002                 if (tcc_state->warn_implicit_function_declaration)
13003                     warning("implicit declaration of function '%s'",
13004                             get_tok_str(t, NULL));
13005                 s = external_global_sym(t, &func_old_type, 0); 
13006             }
13007             if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
13008                 (VT_STATIC | VT_INLINE | VT_FUNC)) {
13009                 /* if referencing an inline function, then we generate a
13010                    symbol to it if not already done. It will have the
13011                    effect to generate code for it at the end of the
13012                    compilation unit. Inline function as always
13013                    generated in the text section. */
13014                 if (!s->c)
13015                     put_extern_sym(s, text_section, 0, 0);
13016                 r = VT_SYM | VT_CONST;
13017             } else {
13018                 r = s->r;
13019             }
13020             vset(&s->type, r, s->c);
13021             /* if forward reference, we must point to s */
13022             if (vtop->r & VT_SYM) {
13023                 vtop->sym = s;
13024                 vtop->c.ul = 0;
13025             }
13026             break;
13027         }
13028         
13029         /* post operations */
13030         while (1) {
13031             if (tok == TOK_INC || tok == TOK_DEC) {
13032                 inc(1, tok);
13033                 next();
13034             } else if (tok == '.' || tok == TOK_ARROW) {
13035                 /* field */ 
13036                 if (tok == TOK_ARROW) 
13037                     indir();
13038                 test_lvalue();
13039                 gaddrof();
13040                 next();
13041                 /* expect pointer on structure */
13042                 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
13043                     expect("struct or union");
13044                 s = vtop->type.ref;
13045                 /* find field */
13046                 tok |= SYM_FIELD;
13047                 while ((s = s->next) != NULL) {
13048                     if (s->v == tok)
13049                         break;
13050                 }
13051                 if (!s)
13052                     error("field not found");
13053                 /* add field offset to pointer */
13054                 vtop->type = char_pointer_type; /* change type to 'char *' */
13055                 vpushi(s->c);
13056                 gen_op('+');
13057                 /* change type to field type, and set to lvalue */
13058                 vtop->type = s->type;
13059                 /* an array is never an lvalue */
13060                 if (!(vtop->type.t & VT_ARRAY)) {
13061                     vtop->r |= lvalue_type(vtop->type.t);
13062                     /* if bound checking, the referenced pointer must be checked */
13063                     if (do_bounds_check) 
13064                         vtop->r |= VT_MUSTBOUND;
13065                 }
13066                 next();
13067             } else if (tok == '[') {
13068                 next();
13069                 gexpr();
13070                 gen_op('+');
13071                 indir();
13072                 skip(']');
13073             } else if (tok == '(') {
13074                 SValue ret;
13075                 Sym *sa;
13076                 int nb_args;
13077     
13078                 /* function call  */
13079                 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
13080                     /* pointer test (no array accepted) */
13081                     if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
13082                         vtop->type = *pointed_type(&vtop->type);
13083                         if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
13084                             goto error_func;
13085                     } else {
13086                     error_func:
13087                         expect("function pointer");
13088                     }
13089                 } else {
13090                     vtop->r &= ~VT_LVAL; /* no lvalue */
13091                 }
13092                 /* get return type */
13093                 s = vtop->type.ref;
13094                 next();
13095                 sa = s->next; /* first parameter */
13096                 nb_args = 0;
13097                 /* compute first implicit argument if a structure is returned */
13098                 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
13099                     /* get some space for the returned structure */
13100                     size = type_size(&s->type, &align);
13101                     loc = (loc - size) & -align;
13102                     ret.type = s->type;
13103                     ret.r = VT_LOCAL | VT_LVAL;
13104                     /* pass it as 'int' to avoid structure arg passing
13105                        problems */
13106                     vseti(VT_LOCAL, loc);
13107                     ret.c = vtop->c;
13108                     nb_args++;
13109                 } else {
13110                     ret.type = s->type; 
13111                     ret.r2 = VT_CONST;
13112                     /* return in register */
13113                     if (is_float(ret.type.t)) {
13114                         ret.r = REG_FRET; 
13115                     } else {
13116                         if ((ret.type.t & VT_BTYPE) == VT_LLONG)
13117                             ret.r2 = REG_LRET;
13118                         ret.r = REG_IRET;
13119                     }
13120                     ret.c.i = 0;
13121                 }
13122                 if (tok != ')') {
13123                     for(;;) {
13124                         expr_eq();
13125                         gfunc_param_typed(s, sa);
13126                         nb_args++;
13127                         if (sa)
13128                             sa = sa->next;
13129                         if (tok == ')')
13130                             break;
13131                         skip(',');
13132                     }
13133                 }
13134                 if (sa)
13135                     error("too few arguments to function");
13136                 skip(')');
13137                 if (!nocode_wanted) {
13138                     gfunc_call(nb_args);
13139                 } else {
13140                     vtop -= (nb_args + 1);
13141                 }
13142                 /* return value */
13143                 vsetc(&ret.type, ret.r, &ret.c);
13144                 vtop->r2 = ret.r2;
13145             } else {
13146                 break;
13147             }
13148         }
13149     }
13150     
13151     static void uneq(void)
13152     {
13153         int t;
13154         
13155         unary();
13156         if (tok == '=' ||
13157             (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
13158             tok == TOK_A_XOR || tok == TOK_A_OR ||
13159             tok == TOK_A_SHL || tok == TOK_A_SAR) {
13160             test_lvalue();
13161             t = tok;
13162             next();
13163             if (t == '=') {
13164                 expr_eq();
13165             } else {
13166                 vdup();
13167                 expr_eq();
13168                 gen_op(t & 0x7f);
13169             }
13170             vstore();
13171         }
13172     }
13173     
13174     static void expr_prod(void)
13175     {
13176         int t;
13177     
13178         uneq();
13179         while (tok == '*' || tok == '/' || tok == '%') {
13180             t = tok;
13181             next();
13182             uneq();
13183             gen_op(t);
13184         }
13185     }
13186     
13187     static void expr_sum(void)
13188     {
13189         int t;
13190     
13191         expr_prod();
13192         while (tok == '+' || tok == '-') {
13193             t = tok;
13194             next();
13195             expr_prod();
13196             gen_op(t);
13197         }
13198     }
13199     
13200     static void expr_shift(void)
13201     {
13202         int t;
13203     
13204         expr_sum();
13205         while (tok == TOK_SHL || tok == TOK_SAR) {
13206             t = tok;
13207             next();
13208             expr_sum();
13209             gen_op(t);
13210         }
13211     }
13212     
13213     static void expr_cmp(void)
13214     {
13215         int t;
13216     
13217         expr_shift();
13218         while ((tok >= TOK_ULE && tok <= TOK_GT) ||
13219                tok == TOK_ULT || tok == TOK_UGE) {
13220             t = tok;
13221             next();
13222             expr_shift();
13223             gen_op(t);
13224         }
13225     }
13226     
13227     static void expr_cmpeq(void)
13228     {
13229         int t;
13230     
13231         expr_cmp();
13232         while (tok == TOK_EQ || tok == TOK_NE) {
13233             t = tok;
13234             next();
13235             expr_cmp();
13236             gen_op(t);
13237         }
13238     }
13239     
13240     static void expr_and(void)
13241     {
13242         expr_cmpeq();
13243         while (tok == '&') {
13244             next();
13245             expr_cmpeq();
13246             gen_op('&');
13247         }
13248     }
13249     
13250     static void expr_xor(void)
13251     {
13252         expr_and();
13253         while (tok == '^') {
13254             next();
13255             expr_and();
13256             gen_op('^');
13257         }
13258     }
13259     
13260     static void expr_or(void)
13261     {
13262         expr_xor();
13263         while (tok == '|') {
13264             next();
13265             expr_xor();
13266             gen_op('|');
13267         }
13268     }
13269     
13270     /* XXX: fix this mess */
13271     static void expr_land_const(void)
13272     {
13273         expr_or();
13274         while (tok == TOK_LAND) {
13275             next();
13276             expr_or();
13277             gen_op(TOK_LAND);
13278         }
13279     }
13280     
13281     /* XXX: fix this mess */
13282     static void expr_lor_const(void)
13283     {
13284         expr_land_const();
13285         while (tok == TOK_LOR) {
13286             next();
13287             expr_land_const();
13288             gen_op(TOK_LOR);
13289         }
13290     }
13291     
13292     /* only used if non constant */
13293     static void expr_land(void)
13294     {
13295         int t;
13296     
13297         expr_or();
13298         if (tok == TOK_LAND) {
13299             t = 0;
13300             for(;;) {
13301                 t = gtst(1, t);
13302                 if (tok != TOK_LAND) {
13303                     vseti(VT_JMPI, t);
13304                     break;
13305                 }
13306                 next();
13307                 expr_or();
13308             }
13309         }
13310     }
13311     
13312     static void expr_lor(void)
13313     {
13314         int t;
13315     
13316         expr_land();
13317         if (tok == TOK_LOR) {
13318             t = 0;
13319             for(;;) {
13320                 t = gtst(0, t);
13321                 if (tok != TOK_LOR) {
13322                     vseti(VT_JMP, t);
13323                     break;
13324                 }
13325                 next();
13326                 expr_land();
13327             }
13328         }
13329     }
13330     
13331     /* XXX: better constant handling */
13332     static void expr_eq(void)
13333     {
13334         int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
13335         SValue sv;
13336         CType type, type1, type2;
13337     
13338         if (const_wanted) {
13339             int c1, c;
13340             expr_lor_const();
13341             if (tok == '?') {
13342                 c = vtop->c.i;
13343                 vpop();
13344                 next();
13345                 if (tok == ':' && gnu_ext) {
13346                     c1 = c;
13347                 } else {
13348                     gexpr();
13349                     c1 = vtop->c.i;
13350                     vpop();
13351                 }
13352                 skip(':');
13353                 expr_eq();
13354                 if (c)
13355                     vtop->c.i = c1;
13356             }
13357         } else {
13358             expr_lor();
13359             if (tok == '?') {
13360                 next();
13361                 if (vtop != vstack) {
13362                     /* needed to avoid having different registers saved in
13363                        each branch */
13364                     if (is_float(vtop->type.t))
13365                         rc = RC_FLOAT;
13366                     else
13367                         rc = RC_INT;
13368                         gv(rc);
13369                         save_regs(1);
13370                 }
13371                 if (tok == ':' && gnu_ext) {
13372                     gv_dup();
13373                     tt = gtst(1, 0);
13374                 } else {
13375                     tt = gtst(1, 0);
13376                     gexpr();
13377                 }
13378                 type1 = vtop->type;
13379                 sv = *vtop; /* save value to handle it later */
13380                 vtop--; /* no vpop so that FP stack is not flushed */
13381                 skip(':');
13382                 u = gjmp(0);
13383                 gsym(tt);
13384                 expr_eq();
13385                 type2 = vtop->type;
13386     
13387                 t1 = type1.t;
13388                 bt1 = t1 & VT_BTYPE;
13389                 t2 = type2.t;
13390                 bt2 = t2 & VT_BTYPE;
13391                 /* cast operands to correct type according to ISOC rules */
13392                 if (is_float(bt1) || is_float(bt2)) {
13393                     if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
13394                         type.t = VT_LDOUBLE;
13395                     } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
13396                         type.t = VT_DOUBLE;
13397                     } else {
13398                         type.t = VT_FLOAT;
13399                     }
13400                 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
13401                     /* cast to biggest op */
13402                     type.t = VT_LLONG;
13403                     /* convert to unsigned if it does not fit in a long long */
13404                     if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
13405                         (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
13406                         type.t |= VT_UNSIGNED;
13407                 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
13408                     /* XXX: test pointer compatibility */
13409                     type = type1;
13410                 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
13411                     /* XXX: test structure compatibility */
13412                     type = type1;
13413                 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
13414                     /* NOTE: as an extension, we accept void on only one side */
13415                     type.t = VT_VOID;
13416                 } else {
13417                     /* integer operations */
13418                     type.t = VT_INT;
13419                     /* convert to unsigned if it does not fit in an integer */
13420                     if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
13421                         (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
13422                         type.t |= VT_UNSIGNED;
13423                 }
13424                     
13425                 /* now we convert second operand */
13426                 gen_cast(&type);
13427                 rc = RC_INT;
13428                 if (is_float(type.t)) {
13429                     rc = RC_FLOAT;
13430                 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
13431                     /* for long longs, we use fixed registers to avoid having
13432                        to handle a complicated move */
13433                     rc = RC_IRET; 
13434                 }
13435                 
13436                 r2 = gv(rc);
13437                 /* this is horrible, but we must also convert first
13438                    operand */
13439                 tt = gjmp(0);
13440                 gsym(u);
13441                 /* put again first value and cast it */
13442                 *vtop = sv;
13443                 gen_cast(&type);
13444                 r1 = gv(rc);
13445                 move_reg(r2, r1);
13446                 vtop->r = r2;
13447                 gsym(tt);
13448             }
13449         }
13450     }
13451     
13452     static void gexpr(void)
13453     {
13454         while (1) {
13455             expr_eq();
13456             if (tok != ',')
13457                 break;
13458             vpop();
13459             next();
13460         }
13461     }
13462     
13463     /* parse an expression and return its type without any side effect. */
13464     static void expr_type(CType *type)
13465     {
13466         int saved_nocode_wanted;
13467     
13468         saved_nocode_wanted = nocode_wanted;
13469         nocode_wanted = 1;
13470         gexpr();
13471         *type = vtop->type;
13472         vpop();
13473         nocode_wanted = saved_nocode_wanted;
13474     }
13475     
13476     /* parse a unary expression and return its type without any side
13477        effect. */
13478     static void unary_type(CType *type)
13479     {
13480         int a;
13481     
13482         a = nocode_wanted;
13483         nocode_wanted = 1;
13484         unary();
13485         *type = vtop->type;
13486         vpop();
13487         nocode_wanted = a;
13488     }
13489     
13490     /* parse a constant expression and return value in vtop.  */
13491     static void expr_const1(void)
13492     {
13493         int a;
13494         a = const_wanted;
13495         const_wanted = 1;
13496         expr_eq();
13497         const_wanted = a;
13498     }
13499     
13500     /* parse an integer constant and return its value. */
13501     static int expr_const(void)
13502     {
13503         int c;
13504         expr_const1();
13505         if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
13506             expect("constant expression");
13507         c = vtop->c.i;
13508         vpop();
13509         return c;
13510     }
13511     
13512     /* return the label token if current token is a label, otherwise
13513        return zero */
13514     static int is_label(void)
13515     {
13516         int last_tok;
13517     
13518         /* fast test first */
13519         if (tok < TOK_UIDENT)
13520             return 0;
13521         /* no need to save tokc because tok is an identifier */
13522         last_tok = tok;
13523         next();
13524         if (tok == ':') {
13525             next();
13526             return last_tok;
13527         } else {
13528             unget_tok(last_tok);
13529             return 0;
13530         }
13531     }
13532     
13533     static void block(int *bsym, int *csym, int *case_sym, int *def_sym, 
13534                       int case_reg, int is_expr)
13535     {
13536         int a, b, c, d;
13537         Sym *s;
13538     
13539         /* generate line number info */
13540         if (do_debug && 
13541             (last_line_num != file->line_num || last_ind != ind)) {
13542             put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
13543             last_ind = ind;
13544             last_line_num = file->line_num;
13545         }
13546     
13547         if (is_expr) {
13548             /* default return value is (void) */
13549             vpushi(0);
13550             vtop->type.t = VT_VOID;
13551         }
13552     
13553         if (tok == TOK_IF) {
13554             /* if test */
13555             next();
13556             skip('(');
13557             gexpr();
13558             skip(')');
13559             a = gtst(1, 0);
13560             block(bsym, csym, case_sym, def_sym, case_reg, 0);
13561             c = tok;
13562             if (c == TOK_ELSE) {
13563                 next();
13564                 d = gjmp(0);
13565                 gsym(a);
13566                 block(bsym, csym, case_sym, def_sym, case_reg, 0);
13567                 gsym(d); /* patch else jmp */
13568             } else
13569                 gsym(a);
13570         } else if (tok == TOK_WHILE) {
13571             next();
13572             d = ind;
13573             skip('(');
13574             gexpr();
13575             skip(')');
13576             a = gtst(1, 0);
13577             b = 0;
13578             block(&a, &b, case_sym, def_sym, case_reg, 0);
13579             gjmp_addr(d);
13580             gsym(a);
13581             gsym_addr(b, d);
13582         } else if (tok == '{') {
13583             Sym *llabel;
13584             
13585             next();
13586             /* record local declaration stack position */
13587             s = local_stack;
13588             llabel = local_label_stack;
13589             /* handle local labels declarations */
13590             if (tok == TOK_LABEL) {
13591                 next();
13592                 for(;;) {
13593                     if (tok < TOK_UIDENT)
13594                         expect("label identifier");
13595                     label_push(&local_label_stack, tok, LABEL_DECLARED);
13596                     next();
13597                     if (tok == ',') {
13598                         next();
13599                     } else {
13600                         skip(';');
13601                         break;
13602                     }
13603                 }
13604             }
13605             while (tok != '}') {
13606                 decl(VT_LOCAL);
13607                 if (tok != '}') {
13608                     if (is_expr)
13609                         vpop();
13610                     block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
13611                 }
13612             }
13613             /* pop locally defined labels */
13614             label_pop(&local_label_stack, llabel);
13615             /* pop locally defined symbols */
13616             sym_pop(&local_stack, s);
13617             next();
13618         } else if (tok == TOK_RETURN) {
13619             next();
13620             if (tok != ';') {
13621                 gexpr();
13622                 gen_assign_cast(&func_vt);
13623                 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
13624                     CType type;
13625                     /* if returning structure, must copy it to implicit
13626                        first pointer arg location */
13627                     type = func_vt;
13628                     mk_pointer(&type);
13629                     vset(&type, VT_LOCAL | VT_LVAL, func_vc);
13630                     indir();
13631                     vswap();
13632                     /* copy structure value to pointer */
13633                     vstore();
13634                 } else if (is_float(func_vt.t)) {
13635                     gv(RC_FRET);
13636                 } else {
13637                     gv(RC_IRET);
13638                 }
13639                 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
13640             }
13641             skip(';');
13642             rsym = gjmp(rsym); /* jmp */
13643         } else if (tok == TOK_BREAK) {
13644             /* compute jump */
13645             if (!bsym)
13646                 error("cannot break");
13647             *bsym = gjmp(*bsym);
13648             next();
13649             skip(';');
13650         } else if (tok == TOK_CONTINUE) {
13651             /* compute jump */
13652             if (!csym)
13653                 error("cannot continue");
13654             *csym = gjmp(*csym);
13655             next();
13656             skip(';');
13657         } else if (tok == TOK_FOR) {
13658             int e;
13659             next();
13660             skip('(');
13661             if (tok != ';') {
13662                 gexpr();
13663                 vpop();
13664             }
13665             skip(';');
13666             d = ind;
13667             c = ind;
13668             a = 0;
13669             b = 0;
13670             if (tok != ';') {
13671                 gexpr();
13672                 a = gtst(1, 0);
13673             }
13674             skip(';');
13675             if (tok != ')') {
13676                 e = gjmp(0);
13677                 c = ind;
13678                 gexpr();
13679                 vpop();
13680                 gjmp_addr(d);
13681                 gsym(e);
13682             }
13683             skip(')');
13684             block(&a, &b, case_sym, def_sym, case_reg, 0);
13685             gjmp_addr(c);
13686             gsym(a);
13687             gsym_addr(b, c);
13688         } else 
13689         if (tok == TOK_DO) {
13690             next();
13691             a = 0;
13692             b = 0;
13693             d = ind;
13694             block(&a, &b, case_sym, def_sym, case_reg, 0);
13695             skip(TOK_WHILE);
13696             skip('(');
13697             gsym(b);
13698             gexpr();
13699             c = gtst(0, 0);
13700             gsym_addr(c, d);
13701             skip(')');
13702             gsym(a);
13703             skip(';');
13704         } else
13705         if (tok == TOK_SWITCH) {
13706             next();
13707             skip('(');
13708             gexpr();
13709             /* XXX: other types than integer */
13710             case_reg = gv(RC_INT);
13711             vpop();
13712             skip(')');
13713             a = 0;
13714             b = gjmp(0); /* jump to first case */
13715             c = 0;
13716             block(&a, csym, &b, &c, case_reg, 0);
13717             /* if no default, jmp after switch */
13718             if (c == 0)
13719                 c = ind;
13720             /* default label */
13721             gsym_addr(b, c);
13722             /* break label */
13723             gsym(a);
13724         } else
13725         if (tok == TOK_CASE) {
13726             int v1, v2;
13727             if (!case_sym)
13728                 expect("switch");
13729             next();
13730             v1 = expr_const();
13731             v2 = v1;
13732             if (gnu_ext && tok == TOK_DOTS) {
13733                 next();
13734                 v2 = expr_const();
13735                 if (v2 < v1)
13736                     warning("empty case range");
13737             }
13738             /* since a case is like a label, we must skip it with a jmp */
13739             b = gjmp(0);
13740             gsym(*case_sym);
13741             vseti(case_reg, 0);
13742             vpushi(v1);
13743             if (v1 == v2) {
13744                 gen_op(TOK_EQ);
13745                 *case_sym = gtst(1, 0);
13746             } else {
13747                 gen_op(TOK_GE);
13748                 *case_sym = gtst(1, 0);
13749                 vseti(case_reg, 0);
13750                 vpushi(v2);
13751                 gen_op(TOK_LE);
13752                 *case_sym = gtst(1, *case_sym);
13753             }
13754             gsym(b);
13755             skip(':');
13756             is_expr = 0;
13757             goto block_after_label;
13758         } else 
13759         if (tok == TOK_DEFAULT) {
13760             next();
13761             skip(':');
13762             if (!def_sym)
13763                 expect("switch");
13764             if (*def_sym)
13765                 error("too many 'default'");
13766             *def_sym = ind;
13767             is_expr = 0;
13768             goto block_after_label;
13769         } else
13770         if (tok == TOK_GOTO) {
13771             next();
13772             if (tok == '*' && gnu_ext) {
13773                 /* computed goto */
13774                 next();
13775                 gexpr();
13776                 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
13777                     expect("pointer");
13778                 ggoto();
13779             } else if (tok >= TOK_UIDENT) {
13780                 s = label_find(tok);
13781                 /* put forward definition if needed */
13782                 if (!s) {
13783                     s = label_push(&global_label_stack, tok, LABEL_FORWARD);
13784                 } else {
13785                     if (s->r == LABEL_DECLARED)
13786                         s->r = LABEL_FORWARD;
13787                 }
13788                 /* label already defined */
13789                 if (s->r & LABEL_FORWARD) 
13790                     s->next = (void *)gjmp((long)s->next);
13791                 else
13792                     gjmp_addr((long)s->next);
13793                 next();
13794             } else {
13795                 expect("label identifier");
13796             }
13797             skip(';');
13798         } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
13799             asm_instr();
13800         } else {
13801             b = is_label();
13802             if (b) {
13803                 /* label case */
13804                 s = label_find(b);
13805                 if (s) {
13806                     if (s->r == LABEL_DEFINED)
13807                         error("duplicate label '%s'", get_tok_str(s->v, NULL));
13808                     gsym((long)s->next);
13809                     s->r = LABEL_DEFINED;
13810                 } else {
13811                     s = label_push(&global_label_stack, b, LABEL_DEFINED);
13812                 }
13813                 s->next = (void *)ind;
13814                 /* we accept this, but it is a mistake */
13815             block_after_label:
13816                 if (tok == '}') {
13817                     warning("deprecated use of label at end of compound statement");
13818                 } else {
13819                     if (is_expr)
13820                         vpop();
13821                     block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
13822                 }
13823             } else {
13824                 /* expression case */
13825                 if (tok != ';') {
13826                     if (is_expr) {
13827                         vpop();
13828                         gexpr();
13829                     } else {
13830                         gexpr();
13831                         vpop();
13832                     }
13833                 }
13834                 skip(';');
13835             }
13836         }
13837     }
13838     
13839     /* t is the array or struct type. c is the array or struct
13840        address. cur_index/cur_field is the pointer to the current
13841        value. 'size_only' is true if only size info is needed (only used
13842        in arrays) */
13843     static void decl_designator(CType *type, Section *sec, unsigned long c, 
13844                                 int *cur_index, Sym **cur_field, 
13845                                 int size_only)
13846     {
13847         Sym *s, *f;
13848         int notfirst, index, index_last, align, l, nb_elems, elem_size;
13849         CType type1;
13850     
13851         notfirst = 0;
13852         elem_size = 0;
13853         nb_elems = 1;
13854         if (gnu_ext && (l = is_label()) != 0)
13855             goto struct_field;
13856         while (tok == '[' || tok == '.') {
13857             if (tok == '[') {
13858                 if (!(type->t & VT_ARRAY))
13859                     expect("array type");
13860                 s = type->ref;
13861                 next();
13862                 index = expr_const();
13863                 if (index < 0 || (s->c >= 0 && index >= s->c))
13864                     expect("invalid index");
13865                 if (tok == TOK_DOTS && gnu_ext) {
13866                     next();
13867                     index_last = expr_const();
13868                     if (index_last < 0 || 
13869                         (s->c >= 0 && index_last >= s->c) ||
13870                         index_last < index)
13871                         expect("invalid index");
13872                 } else {
13873                     index_last = index;
13874                 }
13875                 skip(']');
13876                 if (!notfirst)
13877                     *cur_index = index_last;
13878                 type = pointed_type(type);
13879                 elem_size = type_size(type, &align);
13880                 c += index * elem_size;
13881                 /* NOTE: we only support ranges for last designator */
13882                 nb_elems = index_last - index + 1;
13883                 if (nb_elems != 1) {
13884                     notfirst = 1;
13885                     break;
13886                 }
13887             } else {
13888                 next();
13889                 l = tok;
13890                 next();
13891             struct_field:
13892                 if ((type->t & VT_BTYPE) != VT_STRUCT)
13893                     expect("struct/union type");
13894                 s = type->ref;
13895                 l |= SYM_FIELD;
13896                 f = s->next;
13897                 while (f) {
13898                     if (f->v == l)
13899                         break;
13900                     f = f->next;
13901                 }
13902                 if (!f)
13903                     expect("field");
13904                 if (!notfirst)
13905                     *cur_field = f;
13906                 /* XXX: fix this mess by using explicit storage field */
13907                 type1 = f->type;
13908                 type1.t |= (type->t & ~VT_TYPE);
13909                 type = &type1;
13910                 c += f->c;
13911             }
13912             notfirst = 1;
13913         }
13914         if (notfirst) {
13915             if (tok == '=') {
13916                 next();
13917             } else {
13918                 if (!gnu_ext)
13919                     expect("=");
13920             }
13921         } else {
13922             if (type->t & VT_ARRAY) {
13923                 index = *cur_index;
13924                 type = pointed_type(type);
13925                 c += index * type_size(type, &align);
13926             } else {
13927                 f = *cur_field;
13928                 if (!f)
13929                     error("too many field init");
13930                 /* XXX: fix this mess by using explicit storage field */
13931                 type1 = f->type;
13932                 type1.t |= (type->t & ~VT_TYPE);
13933                 type = &type1;
13934                 c += f->c;
13935             }
13936         }
13937         decl_initializer(type, sec, c, 0, size_only);
13938     
13939         /* XXX: make it more general */
13940         if (!size_only && nb_elems > 1) {
13941             unsigned long c_end;
13942             uint8_t *src, *dst;
13943             int i;
13944     
13945             if (!sec)
13946                 error("range init not supported yet for dynamic storage");
13947             c_end = c + nb_elems * elem_size;
13948             if (c_end > sec->data_allocated)
13949                 section_realloc(sec, c_end);
13950             src = sec->data + c;
13951             dst = src;
13952             for(i = 1; i < nb_elems; i++) {
13953                 dst += elem_size;
13954                 memcpy(dst, src, elem_size);
13955             }
13956         }
13957     }
13958     
13959     #define EXPR_VAL   0
13960     #define EXPR_CONST 1
13961     #define EXPR_ANY   2
13962     
13963     /* store a value or an expression directly in global data or in local array */
13964     static void init_putv(CType *type, Section *sec, unsigned long c, 
13965                           int v, int expr_type)
13966     {
13967         int saved_global_expr, bt, bit_pos, bit_size;
13968         void *ptr;
13969         unsigned long long bit_mask;
13970         CType dtype;
13971     
13972         switch(expr_type) {
13973         case EXPR_VAL:
13974             vpushi(v);
13975             break;
13976         case EXPR_CONST:
13977             /* compound literals must be allocated globally in this case */
13978             saved_global_expr = global_expr;
13979             global_expr = 1;
13980             expr_const1();
13981             global_expr = saved_global_expr;
13982             /* NOTE: symbols are accepted */
13983             if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
13984                 error("initializer element is not constant");
13985             break;
13986         case EXPR_ANY:
13987             expr_eq();
13988             break;
13989         }
13990         
13991         dtype = *type;
13992         dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
13993     
13994         if (sec) {
13995             /* XXX: not portable */
13996             /* XXX: generate error if incorrect relocation */
13997             gen_assign_cast(&dtype);
13998             bt = type->t & VT_BTYPE;
13999             ptr = sec->data + c;
14000             /* XXX: make code faster ? */
14001             if (!(type->t & VT_BITFIELD)) {
14002                 bit_pos = 0;
14003                 bit_size = 32;
14004                 bit_mask = -1LL;
14005             } else {
14006                 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
14007                 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
14008                 bit_mask = (1LL << bit_size) - 1;
14009             }
14010             if ((vtop->r & VT_SYM) &&
14011                 (bt == VT_BYTE ||
14012                  bt == VT_SHORT ||
14013                  bt == VT_DOUBLE ||
14014                  bt == VT_LDOUBLE ||
14015                  bt == VT_LLONG ||
14016                  (bt == VT_INT && bit_size != 32)))
14017                 error("initializer element is not computable at load time");
14018             switch(bt) {
14019             case VT_BYTE:
14020                 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
14021                 break;
14022             case VT_SHORT:
14023                 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
14024                 break;
14025             case VT_DOUBLE:
14026                 *(double *)ptr = vtop->c.d;
14027                 break;
14028             case VT_LDOUBLE:
14029                 *(long double *)ptr = vtop->c.ld;
14030                 break;
14031             case VT_LLONG:
14032                 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
14033                 break;
14034             default:
14035                 if (vtop->r & VT_SYM) {
14036                     greloc(sec, vtop->sym, c, R_DATA_32);
14037                 }
14038                 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
14039                 break;
14040             }
14041             vtop--;
14042         } else {
14043             vset(&dtype, VT_LOCAL, c);
14044             vswap();
14045             vstore();
14046             vpop();
14047         }
14048     }
14049     
14050     /* put zeros for variable based init */
14051     static void init_putz(CType *t, Section *sec, unsigned long c, int size)
14052     {
14053         if (sec) {
14054             /* nothing to do because globals are already set to zero */
14055         } else {
14056             vpush_global_sym(&func_old_type, TOK_memset);
14057             vseti(VT_LOCAL, c);
14058             vpushi(0);
14059             vpushi(size);
14060             gfunc_call(3);
14061         }
14062     }
14063     
14064     /* 't' contains the type and storage info. 'c' is the offset of the
14065        object in section 'sec'. If 'sec' is NULL, it means stack based
14066        allocation. 'first' is true if array '{' must be read (multi
14067        dimension implicit array init handling). 'size_only' is true if
14068        size only evaluation is wanted (only for arrays). */
14069     static void decl_initializer(CType *type, Section *sec, unsigned long c, 
14070                                  int first, int size_only)
14071     {
14072         int index, array_length, n, no_oblock, nb, parlevel, i;
14073         int size1, align1, expr_type;
14074         Sym *s, *f;
14075         CType *t1;
14076     
14077         if (type->t & VT_ARRAY) {
14078             s = type->ref;
14079             n = s->c;
14080             array_length = 0;
14081             t1 = pointed_type(type);
14082             size1 = type_size(t1, &align1);
14083     
14084             no_oblock = 1;
14085             if ((first && tok != TOK_LSTR && tok != TOK_STR) || 
14086                 tok == '{') {
14087                 skip('{');
14088                 no_oblock = 0;
14089             }
14090     
14091             /* only parse strings here if correct type (otherwise: handle
14092                them as ((w)char *) expressions */
14093             if ((tok == TOK_LSTR && 
14094                  (t1->t & VT_BTYPE) == VT_INT) ||
14095                 (tok == TOK_STR &&
14096                  (t1->t & VT_BTYPE) == VT_BYTE)) {
14097                 while (tok == TOK_STR || tok == TOK_LSTR) {
14098                     int cstr_len, ch;
14099                     CString *cstr;
14100     
14101                     cstr = tokc.cstr;
14102                     /* compute maximum number of chars wanted */
14103                     if (tok == TOK_STR)
14104                         cstr_len = cstr->size;
14105                     else
14106                         cstr_len = cstr->size / sizeof(int);
14107                     cstr_len--;
14108                     nb = cstr_len;
14109                     if (n >= 0 && nb > (n - array_length))
14110                         nb = n - array_length;
14111                     if (!size_only) {
14112                         if (cstr_len > nb)
14113                             warning("initializer-string for array is too long");
14114                         /* in order to go faster for common case (char
14115                            string in global variable, we handle it
14116                            specifically */
14117                         if (sec && tok == TOK_STR && size1 == 1) {
14118                             memcpy(sec->data + c + array_length, cstr->data, nb);
14119                         } else {
14120                             for(i=0;i<nb;i++) {
14121                                 if (tok == TOK_STR)
14122                                     ch = ((unsigned char *)cstr->data)[i];
14123                                 else
14124                                     ch = ((int *)cstr->data)[i];
14125                                 init_putv(t1, sec, c + (array_length + i) * size1,
14126                                           ch, EXPR_VAL);
14127                             }
14128                         }
14129                     }
14130                     array_length += nb;
14131                     next();
14132                 }
14133                 /* only add trailing zero if enough storage (no
14134                    warning in this case since it is standard) */
14135                 if (n < 0 || array_length < n) {
14136                     if (!size_only) {
14137                         init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
14138                     }
14139                     array_length++;
14140                 }
14141             } else {
14142                 index = 0;
14143                 while (tok != '}') {
14144                     decl_designator(type, sec, c, &index, NULL, size_only);
14145                     if (n >= 0 && index >= n)
14146                         error("index too large");
14147                     /* must put zero in holes (note that doing it that way
14148                        ensures that it even works with designators) */
14149                     if (!size_only && array_length < index) {
14150                         init_putz(t1, sec, c + array_length * size1, 
14151                                   (index - array_length) * size1);
14152                     }
14153                     index++;
14154                     if (index > array_length)
14155                         array_length = index;
14156                     /* special test for multi dimensional arrays (may not
14157                        be strictly correct if designators are used at the
14158                        same time) */
14159                     if (index >= n && no_oblock)
14160                         break;
14161                     if (tok == '}')
14162                         break;
14163                     skip(',');
14164                 }
14165             }
14166             if (!no_oblock)
14167                 skip('}');
14168             /* put zeros at the end */
14169             if (!size_only && n >= 0 && array_length < n) {
14170                 init_putz(t1, sec, c + array_length * size1, 
14171                           (n - array_length) * size1);
14172             }
14173             /* patch type size if needed */
14174             if (n < 0)
14175                 s->c = array_length;
14176         } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
14177                    (sec || !first || tok == '{')) {
14178             int par_count;
14179     
14180             /* NOTE: the previous test is a specific case for automatic
14181                struct/union init */
14182             /* XXX: union needs only one init */
14183     
14184             /* XXX: this test is incorrect for local initializers
14185                beginning with ( without {. It would be much more difficult
14186                to do it correctly (ideally, the expression parser should
14187                be used in all cases) */
14188             par_count = 0;
14189             if (tok == '(') {
14190                 AttributeDef ad1;
14191                 CType type1;
14192                 next();
14193                 while (tok == '(') {
14194                     par_count++;
14195                     next();
14196                 }
14197                 if (!parse_btype(&type1, &ad1))
14198                     expect("cast");
14199                 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
14200     #if 0
14201                 if (!is_assignable_types(type, &type1))
14202                     error("invalid type for cast");
14203     #endif
14204                 skip(')');
14205             }
14206             no_oblock = 1;
14207             if (first || tok == '{') {
14208                 skip('{');
14209                 no_oblock = 0;
14210             }
14211             s = type->ref;
14212             f = s->next;
14213             array_length = 0;
14214             index = 0;
14215             n = s->c;
14216             while (tok != '}') {
14217                 decl_designator(type, sec, c, NULL, &f, size_only);
14218                 index = f->c;
14219                 if (!size_only && array_length < index) {
14220                     init_putz(type, sec, c + array_length, 
14221                               index - array_length);
14222                 }
14223                 index = index + type_size(&f->type, &align1);
14224                 if (index > array_length)
14225                     array_length = index;
14226                 f = f->next;
14227                 if (no_oblock && f == NULL)
14228                     break;
14229                 if (tok == '}')
14230                     break;
14231                 skip(',');
14232             }
14233             /* put zeros at the end */
14234             if (!size_only && array_length < n) {
14235                 init_putz(type, sec, c + array_length, 
14236                           n - array_length);
14237             }
14238             if (!no_oblock)
14239                 skip('}');
14240             while (par_count) {
14241                 skip(')');
14242                 par_count--;
14243             }
14244         } else if (tok == '{') {
14245             next();
14246             decl_initializer(type, sec, c, first, size_only);
14247             skip('}');
14248         } else if (size_only) {
14249             /* just skip expression */
14250             parlevel = 0;
14251             while ((parlevel > 0 || (tok != '}' && tok != ',')) && 
14252                    tok != -1) {
14253                 if (tok == '(')
14254                     parlevel++;
14255                 else if (tok == ')')
14256                     parlevel--;
14257                 next();
14258             }
14259         } else {
14260             /* currently, we always use constant expression for globals
14261                (may change for scripting case) */
14262             expr_type = EXPR_CONST;
14263             if (!sec)
14264                 expr_type = EXPR_ANY;
14265             init_putv(type, sec, c, 0, expr_type);
14266         }
14267     }
14268     
14269     /* parse an initializer for type 't' if 'has_init' is non zero, and
14270        allocate space in local or global data space ('r' is either
14271        VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
14272        variable 'v' of scope 'scope' is declared before initializers are
14273        parsed. If 'v' is zero, then a reference to the new object is put
14274        in the value stack. If 'has_init' is 2, a special parsing is done
14275        to handle string constants. */
14276     static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, 
14277                                        int has_init, int v, int scope)
14278     {
14279         int size, align, addr, data_offset;
14280         int level;
14281         ParseState saved_parse_state;
14282         TokenString init_str;
14283         Section *sec;
14284     
14285         size = type_size(type, &align);
14286         /* If unknown size, we must evaluate it before
14287            evaluating initializers because
14288            initializers can generate global data too
14289            (e.g. string pointers or ISOC99 compound
14290            literals). It also simplifies local
14291            initializers handling */
14292         tok_str_new(&init_str);
14293         if (size < 0) {
14294             if (!has_init) 
14295                 error("unknown type size");
14296             /* get all init string */
14297             if (has_init == 2) {
14298                 /* only get strings */
14299                 while (tok == TOK_STR || tok == TOK_LSTR) {
14300                     tok_str_add_tok(&init_str);
14301                     next();
14302                 }
14303             } else {
14304                 level = 0;
14305                 while (level > 0 || (tok != ',' && tok != ';')) {
14306                     if (tok < 0)
14307                         error("unexpected end of file in initializer");
14308                     tok_str_add_tok(&init_str);
14309                     if (tok == '{')
14310                         level++;
14311                     else if (tok == '}') {
14312                         if (level == 0)
14313                             break;
14314                         level--;
14315                     }
14316                     next();
14317                 }
14318             }
14319             tok_str_add(&init_str, -1);
14320             tok_str_add(&init_str, 0);
14321             
14322             /* compute size */
14323             save_parse_state(&saved_parse_state);
14324     
14325             macro_ptr = init_str.str;
14326             next();
14327             decl_initializer(type, NULL, 0, 1, 1);
14328             /* prepare second initializer parsing */
14329             macro_ptr = init_str.str;
14330             next();
14331             
14332             /* if still unknown size, error */
14333             size = type_size(type, &align);
14334             if (size < 0) 
14335                 error("unknown type size");
14336         }
14337         /* take into account specified alignment if bigger */
14338         if (ad->aligned) {
14339             if (ad->aligned > align)
14340                 align = ad->aligned;
14341         } else if (ad->packed) {
14342             align = 1;
14343         }
14344         if ((r & VT_VALMASK) == VT_LOCAL) {
14345             sec = NULL;
14346             if (do_bounds_check && (type->t & VT_ARRAY)) 
14347                 loc--;
14348             loc = (loc - size) & -align;
14349             addr = loc;
14350             /* handles bounds */
14351             /* XXX: currently, since we do only one pass, we cannot track
14352                '&' operators, so we add only arrays */
14353             if (do_bounds_check && (type->t & VT_ARRAY)) {
14354                 unsigned long *bounds_ptr;
14355                 /* add padding between regions */
14356                 loc--;
14357                 /* then add local bound info */
14358                 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
14359                 bounds_ptr[0] = addr;
14360                 bounds_ptr[1] = size;
14361             }
14362             if (v) {
14363                 /* local variable */
14364                 sym_push(v, type, r, addr);
14365             } else {
14366                 /* push local reference */
14367                 vset(type, r, addr);
14368             }
14369         } else {
14370             Sym *sym;
14371     
14372             sym = NULL;
14373             if (v && scope == VT_CONST) {
14374                 /* see if the symbol was already defined */
14375                 sym = sym_find(v);
14376                 if (sym) {
14377                     if (!is_compatible_types(&sym->type, type))
14378                         error("incompatible types for redefinition of '%s'", 
14379                               get_tok_str(v, NULL));
14380                     if (sym->type.t & VT_EXTERN) {
14381                         /* if the variable is extern, it was not allocated */
14382                         sym->type.t &= ~VT_EXTERN;
14383                         /* set array size if it was ommited in extern
14384                            declaration */
14385                         if ((sym->type.t & VT_ARRAY) && 
14386                             sym->type.ref->c < 0 &&
14387                             type->ref->c >= 0)
14388                             sym->type.ref->c = type->ref->c;
14389                     } else {
14390                         /* we accept several definitions of the same
14391                            global variable. this is tricky, because we
14392                            must play with the SHN_COMMON type of the symbol */
14393                         /* XXX: should check if the variable was already
14394                            initialized. It is incorrect to initialized it
14395                            twice */
14396                         /* no init data, we won't add more to the symbol */
14397                         if (!has_init)
14398                             goto no_alloc;
14399                     }
14400                 }
14401             }
14402     
14403             /* allocate symbol in corresponding section */
14404             sec = ad->section;
14405             if (!sec) {
14406                 if (has_init)
14407                     sec = data_section;
14408                 else if (tcc_state->nocommon)
14409                     sec = bss_section;
14410             }
14411             if (sec) {
14412                 data_offset = sec->data_offset;
14413                 data_offset = (data_offset + align - 1) & -align;
14414                 addr = data_offset;
14415                 /* very important to increment global pointer at this time
14416                    because initializers themselves can create new initializers */
14417                 data_offset += size;
14418                 /* add padding if bound check */
14419                 if (do_bounds_check)
14420                     data_offset++;
14421                 sec->data_offset = data_offset;
14422                 /* allocate section space to put the data */
14423                 if (sec->sh_type != SHT_NOBITS && 
14424                     data_offset > sec->data_allocated)
14425                     section_realloc(sec, data_offset);
14426                 /* align section if needed */
14427                 if (align > sec->sh_addralign)
14428                     sec->sh_addralign = align;
14429             } else {
14430                 addr = 0; /* avoid warning */
14431             }
14432     
14433             if (v) {
14434                 if (scope == VT_CONST) {
14435                     if (!sym)
14436                         goto do_def;
14437                 } else {
14438                 do_def:
14439                     sym = sym_push(v, type, r | VT_SYM, 0);
14440                 }
14441                 /* update symbol definition */
14442                 if (sec) {
14443                     put_extern_sym(sym, sec, addr, size);
14444                 } else {
14445                     Elf32_Sym *esym;
14446                     /* put a common area */
14447                     put_extern_sym(sym, NULL, align, size);
14448                     /* XXX: find a nicer way */
14449                     esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
14450                     esym->st_shndx = SHN_COMMON;
14451                 }
14452             } else {
14453                 CValue cval;
14454     
14455                 /* push global reference */
14456                 sym = get_sym_ref(type, sec, addr, size);
14457                 cval.ul = 0;
14458                 vsetc(type, VT_CONST | VT_SYM, &cval);
14459                 vtop->sym = sym;
14460             }
14461     
14462             /* handles bounds now because the symbol must be defined
14463                before for the relocation */
14464             if (do_bounds_check) {
14465                 unsigned long *bounds_ptr;
14466     
14467                 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
14468                 /* then add global bound info */
14469                 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
14470                 bounds_ptr[0] = 0; /* relocated */
14471                 bounds_ptr[1] = size;
14472             }
14473         }
14474         if (has_init) {
14475             decl_initializer(type, sec, addr, 1, 0);
14476             /* restore parse state if needed */
14477             if (init_str.str) {
14478                 tok_str_free(init_str.str);
14479                 restore_parse_state(&saved_parse_state);
14480             }
14481         }
14482      no_alloc: ;
14483     }
14484     
14485     void put_func_debug(Sym *sym)
14486     {
14487         char buf[512];
14488     
14489         /* stabs info */
14490         /* XXX: we put here a dummy type */
14491         snprintf(buf, sizeof(buf), "%s:%c1", 
14492                  funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
14493         put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
14494                     cur_text_section, sym->c);
14495         last_ind = 0;
14496         last_line_num = 0;
14497     }
14498     
14499     /* parse an old style function declaration list */
14500     /* XXX: check multiple parameter */
14501     static void func_decl_list(Sym *func_sym)
14502     {
14503         AttributeDef ad;
14504         int v;
14505         Sym *s;
14506         CType btype, type;
14507     
14508         /* parse each declaration */
14509         while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) {
14510             if (!parse_btype(&btype, &ad)) 
14511                 expect("declaration list");
14512             if (((btype.t & VT_BTYPE) == VT_ENUM ||
14513                  (btype.t & VT_BTYPE) == VT_STRUCT) && 
14514                 tok == ';') {
14515                 /* we accept no variable after */
14516             } else {
14517                 for(;;) {
14518                     type = btype;
14519                     type_decl(&type, &ad, &v, TYPE_DIRECT);
14520                     /* find parameter in function parameter list */
14521                     s = func_sym->next;
14522                     while (s != NULL) {
14523                         if ((s->v & ~SYM_FIELD) == v)
14524                             goto found;
14525                         s = s->next;
14526                     }
14527                     error("declaration for parameter '%s' but no such parameter",
14528                           get_tok_str(v, NULL));
14529                 found:
14530                     /* check that no storage specifier except 'register' was given */
14531                     if (type.t & VT_STORAGE)
14532                         error("storage class specified for '%s'", get_tok_str(v, NULL)); 
14533                     convert_parameter_type(&type);
14534                     /* we can add the type (NOTE: it could be local to the function) */
14535                     s->type = type;
14536                     /* accept other parameters */
14537                     if (tok == ',')
14538                         next();
14539                     else
14540                         break;
14541                 }
14542             }
14543             skip(';');
14544         }
14545     }
14546     
14547     /* parse a function defined by symbol 'sym' and generate its code in
14548        'cur_text_section' */
14549     static void gen_function(Sym *sym)
14550     {
14551         ind = cur_text_section->data_offset;
14552         /* NOTE: we patch the symbol size later */
14553         put_extern_sym(sym, cur_text_section, ind, 0);
14554         funcname = get_tok_str(sym->v, NULL);
14555         func_ind = ind;
14556         /* put debug symbol */
14557         if (do_debug)
14558             put_func_debug(sym);
14559         /* push a dummy symbol to enable local sym storage */
14560         sym_push2(&local_stack, SYM_FIELD, 0, 0);
14561         gfunc_prolog(&sym->type);
14562         rsym = 0;
14563         block(NULL, NULL, NULL, NULL, 0, 0);
14564         gsym(rsym);
14565         gfunc_epilog();
14566         cur_text_section->data_offset = ind;
14567         label_pop(&global_label_stack, NULL);
14568         sym_pop(&local_stack, NULL); /* reset local stack */
14569         /* end of function */
14570         /* patch symbol size */
14571         ((Elf32_Sym *)symtab_section->data)[sym->c].st_size = 
14572             ind - func_ind;
14573         if (do_debug) {
14574             put_stabn(N_FUN, 0, 0, ind - func_ind);
14575         }
14576         funcname = ""; /* for safety */
14577         func_vt.t = VT_VOID; /* for safety */
14578         ind = 0; /* for safety */
14579     }
14580     
14581     static void gen_inline_functions(void)
14582     {
14583         Sym *sym;
14584         CType *type;
14585         int *str, inline_generated;
14586     
14587         /* iterate while inline function are referenced */
14588         for(;;) {
14589             inline_generated = 0;
14590             for(sym = global_stack; sym != NULL; sym = sym->prev) {
14591                 type = &sym->type;
14592                 if (((type->t & VT_BTYPE) == VT_FUNC) &&
14593                     (type->t & (VT_STATIC | VT_INLINE)) == 
14594                     (VT_STATIC | VT_INLINE) &&
14595                     sym->c != 0) {
14596                     /* the function was used: generate its code and
14597                        convert it to a normal function */
14598                     str = (int *)sym->r;
14599                     sym->r = VT_SYM | VT_CONST;
14600                     type->t &= ~VT_INLINE;
14601     
14602                     macro_ptr = str;
14603                     next();
14604                     cur_text_section = text_section;
14605                     gen_function(sym);
14606                     macro_ptr = NULL; /* fail safe */
14607     
14608                     tok_str_free(str);
14609                     inline_generated = 1;
14610                 }
14611             }
14612             if (!inline_generated)
14613                 break;
14614         }
14615     
14616         /* free all remaining inline function tokens */
14617         for(sym = global_stack; sym != NULL; sym = sym->prev) {
14618             type = &sym->type;
14619             if (((type->t & VT_BTYPE) == VT_FUNC) &&
14620                 (type->t & (VT_STATIC | VT_INLINE)) == 
14621                 (VT_STATIC | VT_INLINE)) {
14622                 str = (int *)sym->r;
14623                 tok_str_free(str);
14624                 sym->r = 0; /* fail safe */
14625             }
14626         }
14627     }
14628     
14629     /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
14630     static void decl(int l)
14631     {
14632         int v, has_init, r;
14633         CType type, btype;
14634         Sym *sym;
14635         AttributeDef ad;
14636         
14637         while (1) {
14638             if (!parse_btype(&btype, &ad)) {
14639                 /* skip redundant ';' */
14640                 /* XXX: find more elegant solution */
14641                 if (tok == ';') {
14642                     next();
14643                     continue;
14644                 }
14645                 if (l == VT_CONST &&
14646                     (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
14647                     /* global asm block */
14648                     asm_global_instr();
14649                     continue;
14650                 }
14651                 /* special test for old K&R protos without explicit int
14652                    type. Only accepted when defining global data */
14653                 if (l == VT_LOCAL || tok < TOK_DEFINE)
14654                     break;
14655                 btype.t = VT_INT;
14656             }
14657             if (((btype.t & VT_BTYPE) == VT_ENUM ||
14658                  (btype.t & VT_BTYPE) == VT_STRUCT) && 
14659                 tok == ';') {
14660                 /* we accept no variable after */
14661                 next();
14662                 continue;
14663             }
14664             while (1) { /* iterate thru each declaration */
14665                 type = btype;
14666                 type_decl(&type, &ad, &v, TYPE_DIRECT);
14667     #if 0
14668                 {
14669                     char buf[500];
14670                     type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
14671                     printf("type = '%s'\n", buf);
14672                 }
14673     #endif
14674                 if ((type.t & VT_BTYPE) == VT_FUNC) {
14675                     /* if old style function prototype, we accept a
14676                        declaration list */
14677                     sym = type.ref;
14678                     if (sym->c == FUNC_OLD)
14679                         func_decl_list(sym);
14680                 }
14681     
14682                 if (tok == '{') {
14683                     if (l == VT_LOCAL)
14684                         error("cannot use local functions");
14685                     if (!(type.t & VT_FUNC))
14686                         expect("function definition");
14687     
14688                     /* reject abstract declarators in function definition */
14689                     sym = type.ref;
14690                     while ((sym = sym->next) != NULL)
14691                         if (!(sym->v & ~SYM_FIELD))
14692                            expect("identifier");
14693                     
14694                     /* XXX: cannot do better now: convert extern line to static inline */
14695                     if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
14696                         type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
14697                     
14698                     sym = sym_find(v);
14699                     if (sym) {
14700                         if ((sym->type.t & VT_BTYPE) != VT_FUNC)
14701                             goto func_error1;
14702                         /* specific case: if not func_call defined, we put
14703                            the one of the prototype */
14704                         /* XXX: should have default value */
14705                         if (sym->type.ref->r != FUNC_CDECL &&
14706                             type.ref->r == FUNC_CDECL)
14707                             type.ref->r = sym->type.ref->r;
14708                         if (!is_compatible_types(&sym->type, &type)) {
14709                         func_error1:
14710                             error("incompatible types for redefinition of '%s'", 
14711                                   get_tok_str(v, NULL));
14712                         }
14713                         /* if symbol is already defined, then put complete type */
14714                         sym->type = type;
14715                     } else {
14716                         /* put function symbol */
14717                         sym = global_identifier_push(v, type.t, 0);
14718                         sym->type.ref = type.ref;
14719                     }
14720     
14721                     /* static inline functions are just recorded as a kind
14722                        of macro. Their code will be emitted at the end of
14723                        the compilation unit only if they are used */
14724                     if ((type.t & (VT_INLINE | VT_STATIC)) == 
14725                         (VT_INLINE | VT_STATIC)) {
14726                         TokenString func_str;
14727                         int block_level;
14728                                
14729                         tok_str_new(&func_str);
14730                         
14731                         block_level = 0;
14732                         for(;;) {
14733                             int t;
14734                             if (tok == TOK_EOF)
14735                                 error("unexpected end of file");
14736                             tok_str_add_tok(&func_str);
14737                             t = tok;
14738                             next();
14739                             if (t == '{') {
14740                                 block_level++;
14741                             } else if (t == '}') {
14742                                 block_level--;
14743                                 if (block_level == 0)
14744                                     break;
14745                             }
14746                         }
14747                         tok_str_add(&func_str, -1);
14748                         tok_str_add(&func_str, 0);
14749                         sym->r = (long)func_str.str;
14750                     } else {
14751                         /* compute text section */
14752                         cur_text_section = ad.section;
14753                         if (!cur_text_section)
14754                             cur_text_section = text_section;
14755                         sym->r = VT_SYM | VT_CONST;
14756                         gen_function(sym);
14757     #ifdef TCC_TARGET_PE
14758                         if (ad.dllexport) {
14759                             ((Elf32_Sym *)symtab_section->data)[sym->c].st_other |= 1;
14760                         }
14761     #endif
14762                     }
14763                     break;
14764                 } else {
14765                     if (btype.t & VT_TYPEDEF) {
14766                         /* save typedefed type  */
14767                         /* XXX: test storage specifiers ? */
14768                         sym = sym_push(v, &type, 0, 0);
14769                         sym->type.t |= VT_TYPEDEF;
14770                     } else if ((type.t & VT_BTYPE) == VT_FUNC) {
14771                         /* external function definition */
14772                         /* specific case for func_call attribute */
14773                         if (ad.func_call)
14774                             type.ref->r = ad.func_call;
14775                         external_sym(v, &type, 0);
14776                     } else {
14777                         /* not lvalue if array */
14778                         r = 0;
14779                         if (!(type.t & VT_ARRAY))
14780                             r |= lvalue_type(type.t);
14781                         has_init = (tok == '=');
14782                         if ((btype.t & VT_EXTERN) || 
14783                             ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
14784                              !has_init && l == VT_CONST && type.ref->c < 0)) {
14785                             /* external variable */
14786                             /* NOTE: as GCC, uninitialized global static
14787                                arrays of null size are considered as
14788                                extern */
14789                             external_sym(v, &type, r);
14790                         } else {
14791                             if (type.t & VT_STATIC)
14792                                 r |= VT_CONST;
14793                             else
14794                                 r |= l;
14795                             if (has_init)
14796                                 next();
14797                             decl_initializer_alloc(&type, &ad, r, 
14798                                                    has_init, v, l);
14799                         }
14800                     }
14801                     if (tok != ',') {
14802                         skip(';');
14803                         break;
14804                     }
14805                     next();
14806                 }
14807             }
14808         }
14809     }
14810     
14811     /* better than nothing, but needs extension to handle '-E' option
14812        correctly too */
14813     static void preprocess_init(TCCState *s1)
14814     {
14815         s1->include_stack_ptr = s1->include_stack;
14816         /* XXX: move that before to avoid having to initialize
14817            file->ifdef_stack_ptr ? */
14818         s1->ifdef_stack_ptr = s1->ifdef_stack;
14819         file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
14820     
14821         /* XXX: not ANSI compliant: bound checking says error */
14822         vtop = vstack - 1;
14823         s1->pack_stack[0] = 0;
14824         s1->pack_stack_ptr = s1->pack_stack;
14825     }
14826     
14827     /* compile the C file opened in 'file'. Return non zero if errors. */
14828     static int tcc_compile(TCCState *s1)
14829     {
14830         Sym *define_start;
14831         char buf[512];
14832         volatile int section_sym;
14833     
14834     #ifdef INC_DEBUG
14835         printf("%s: **** new file\n", file->filename);
14836     #endif
14837         preprocess_init(s1);
14838     
14839         funcname = "";
14840         anon_sym = SYM_FIRST_ANOM; 
14841     
14842         /* file info: full path + filename */
14843         section_sym = 0; /* avoid warning */
14844         if (do_debug) {
14845             section_sym = put_elf_sym(symtab_section, 0, 0, 
14846                                       ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0, 
14847                                       text_section->sh_num, NULL);
14848             dummy_char_star = getcwd(buf, sizeof(buf));
14849             pstrcat(buf, sizeof(buf), "/");
14850             put_stabs_r(buf, N_SO, 0, 0, 
14851                         text_section->data_offset, text_section, section_sym);
14852             put_stabs_r(file->filename, N_SO, 0, 0, 
14853                         text_section->data_offset, text_section, section_sym);
14854         }
14855         /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
14856            symbols can be safely used */
14857         put_elf_sym(symtab_section, 0, 0, 
14858                     ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0, 
14859                     SHN_ABS, file->filename);
14860     
14861         /* define some often used types */
14862         int_type.t = VT_INT;
14863     
14864         char_pointer_type.t = VT_BYTE;
14865         mk_pointer(&char_pointer_type);
14866     
14867         func_old_type.t = VT_FUNC;
14868         func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
14869     
14870     #if 0
14871         /* define 'void *alloca(unsigned int)' builtin function */
14872         {
14873             Sym *s1;
14874     
14875             p = anon_sym++;
14876             sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
14877             s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0);
14878             s1->next = NULL;
14879             sym->next = s1;
14880             sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
14881         }
14882     #endif
14883     
14884         define_start = define_stack;
14885     
14886         if (setjmp(s1->error_jmp_buf) == 0) {
14887             s1->nb_errors = 0;
14888             s1->error_set_jmp_enabled = 1;
14889     
14890             ch = file->buf_ptr[0];
14891             tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
14892             parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM;
14893             next();
14894             decl(VT_CONST);
14895             if (tok != TOK_EOF)
14896                 expect("declaration");
14897     
14898             /* end of translation unit info */
14899             if (do_debug) {
14900                 put_stabs_r(NULL, N_SO, 0, 0, 
14901                             text_section->data_offset, text_section, section_sym);
14902             }
14903         }
14904         s1->error_set_jmp_enabled = 0;
14905     
14906         /* reset define stack, but leave -Dsymbols (may be incorrect if
14907            they are undefined) */
14908         free_defines(define_start); 
14909     
14910         gen_inline_functions();
14911     
14912         sym_pop(&global_stack, NULL);
14913     
14914         return s1->nb_errors != 0 ? -1 : 0;
14915     }
14916     
14917     #ifdef LIBTCC
14918     int tcc_compile_string(TCCState *s, const char *str)
14919     {
14920         BufferedFile bf1, *bf = &bf1;
14921         int ret, len;
14922         char *buf;
14923     
14924         /* init file structure */
14925         bf->fd = -1;
14926         /* XXX: avoid copying */
14927         len = strlen(str);
14928         buf = tcc_malloc(len + 1);
14929         if (!buf)
14930             return -1;
14931         memcpy(buf, str, len);
14932         buf[len] = CH_EOB;
14933         bf->buf_ptr = buf;
14934         bf->buf_end = buf + len;
14935         pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
14936         bf->line_num = 1;
14937         file = bf;
14938         
14939         ret = tcc_compile(s);
14940         
14941         tcc_free(buf);
14942     
14943         /* currently, no need to close */
14944         return ret;
14945     }
14946     #endif
14947     
14948     /* define a preprocessor symbol. A value can also be provided with the '=' operator */
14949     void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
14950     {
14951         BufferedFile bf1, *bf = &bf1;
14952     
14953         pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
14954         pstrcat(bf->buffer, IO_BUF_SIZE, " ");
14955         /* default value */
14956         if (!value) 
14957             value = "1";
14958         pstrcat(bf->buffer, IO_BUF_SIZE, value);
14959         
14960         /* init file structure */
14961         bf->fd = -1;
14962         bf->buf_ptr = bf->buffer;
14963         bf->buf_end = bf->buffer + strlen(bf->buffer);
14964         *bf->buf_end = CH_EOB;
14965         bf->filename[0] = '\0';
14966         bf->line_num = 1;
14967         file = bf;
14968         
14969         s1->include_stack_ptr = s1->include_stack;
14970     
14971         /* parse with define parser */
14972         ch = file->buf_ptr[0];
14973         next_nomacro();
14974         parse_define();
14975         file = NULL;
14976     }
14977     
14978     /* undefine a preprocessor symbol */
14979     void tcc_undefine_symbol(TCCState *s1, const char *sym)
14980     {
14981         TokenSym *ts;
14982         Sym *s;
14983         ts = tok_alloc(sym, strlen(sym));
14984         s = define_find(ts->tok);
14985         /* undefine symbol by putting an invalid name */
14986         if (s)
14987             define_undef(s);
14988     }
14989     
14990     #ifdef CONFIG_TCC_ASM
14991     
14992     #ifdef TCC_TARGET_I386
14993     // njn: inlined i386-asm.c
14994     //#include "i386-asm.c"
14995     //---------------------------------------------------------------------------
14996     /*
14997      *  i386 specific functions for TCC assembler
14998      * 
14999      *  Copyright (c) 2001, 2002 Fabrice Bellard
15000      *
15001      * This library is free software; you can redistribute it and/or
15002      * modify it under the terms of the GNU Lesser General Public
15003      * License as published by the Free Software Foundation; either
15004      * version 2 of the License, or (at your option) any later version.
15005      *
15006      * This library is distributed in the hope that it will be useful,
15007      * but WITHOUT ANY WARRANTY; without even the implied warranty of
15008      * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15009      * Lesser General Public License for more details.
15010      *
15011      * You should have received a copy of the GNU Lesser General Public
15012      * License along with this library; if not, write to the Free Software
15013      * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15014      */
15015     
15016     #define MAX_OPERANDS 3
15017     
15018     typedef struct ASMInstr {
15019         uint16_t sym;
15020         uint16_t opcode;
15021         uint16_t instr_type;
15022     #define OPC_JMP       0x01  /* jmp operand */
15023     #define OPC_B         0x02  /* only used zith OPC_WL */
15024     #define OPC_WL        0x04  /* accepts w, l or no suffix */
15025     #define OPC_BWL       (OPC_B | OPC_WL) /* accepts b, w, l or no suffix */
15026     #define OPC_REG       0x08 /* register is added to opcode */
15027     #define OPC_MODRM     0x10 /* modrm encoding */
15028     #define OPC_FWAIT     0x20 /* add fwait opcode */
15029     #define OPC_TEST      0x40 /* test opcodes */
15030     #define OPC_SHIFT     0x80 /* shift opcodes */
15031     #define OPC_D16      0x0100 /* generate data16 prefix */
15032     #define OPC_ARITH    0x0200 /* arithmetic opcodes */
15033     #define OPC_SHORTJMP 0x0400 /* short jmp operand */
15034     #define OPC_FARITH   0x0800 /* FPU arithmetic opcodes */
15035     #define OPC_GROUP_SHIFT 13
15036     
15037     /* in order to compress the operand type, we use specific operands and
15038        we or only with EA  */ 
15039     #define OPT_REG8  0 /* warning: value is hardcoded from TOK_ASM_xxx */
15040     #define OPT_REG16 1 /* warning: value is hardcoded from TOK_ASM_xxx */
15041     #define OPT_REG32 2 /* warning: value is hardcoded from TOK_ASM_xxx */
15042     #define OPT_MMX   3 /* warning: value is hardcoded from TOK_ASM_xxx */
15043     #define OPT_SSE   4 /* warning: value is hardcoded from TOK_ASM_xxx */
15044     #define OPT_CR    5 /* warning: value is hardcoded from TOK_ASM_xxx */
15045     #define OPT_TR    6 /* warning: value is hardcoded from TOK_ASM_xxx */
15046     #define OPT_DB    7 /* warning: value is hardcoded from TOK_ASM_xxx */
15047     #define OPT_SEG   8
15048     #define OPT_ST    9
15049     #define OPT_IM8   10
15050     #define OPT_IM8S  11
15051     #define OPT_IM16  12
15052     #define OPT_IM32  13
15053     #define OPT_EAX   14 /* %al, %ax or %eax register */
15054     #define OPT_ST0   15 /* %st(0) register */
15055     #define OPT_CL    16 /* %cl register */
15056     #define OPT_DX    17 /* %dx register */
15057     #define OPT_ADDR  18 /* OP_EA with only offset */
15058     #define OPT_INDIR 19 /* *(expr) */
15059     
15060     /* composite types */ 
15061     #define OPT_COMPOSITE_FIRST   20
15062     #define OPT_IM       20 /* IM8 | IM16 | IM32 */
15063     #define OPT_REG      21 /* REG8 | REG16 | REG32 */ 
15064     #define OPT_REGW     22 /* REG16 | REG32 */
15065     #define OPT_IMW      23 /* IM16 | IM32 */ 
15066     
15067     /* can be ored with any OPT_xxx */
15068     #define OPT_EA    0x80
15069     
15070         uint8_t nb_ops;
15071         uint8_t op_type[MAX_OPERANDS]; /* see OP_xxx */
15072     } ASMInstr;
15073     
15074     typedef struct Operand {
15075         uint32_t type;
15076     #define OP_REG8   (1 << OPT_REG8)
15077     #define OP_REG16  (1 << OPT_REG16)
15078     #define OP_REG32  (1 << OPT_REG32)
15079     #define OP_MMX    (1 << OPT_MMX)
15080     #define OP_SSE    (1 << OPT_SSE)
15081     #define OP_CR     (1 << OPT_CR)
15082     #define OP_TR     (1 << OPT_TR)
15083     #define OP_DB     (1 << OPT_DB)
15084     #define OP_SEG    (1 << OPT_SEG)
15085     #define OP_ST     (1 << OPT_ST)
15086     #define OP_IM8    (1 << OPT_IM8)
15087     #define OP_IM8S   (1 << OPT_IM8S)
15088     #define OP_IM16   (1 << OPT_IM16)
15089     #define OP_IM32   (1 << OPT_IM32)
15090     #define OP_EAX    (1 << OPT_EAX)
15091     #define OP_ST0    (1 << OPT_ST0)
15092     #define OP_CL     (1 << OPT_CL)
15093     #define OP_DX     (1 << OPT_DX)
15094     #define OP_ADDR   (1 << OPT_ADDR)
15095     #define OP_INDIR  (1 << OPT_INDIR)
15096     
15097     #define OP_EA     0x40000000
15098     #define OP_REG    (OP_REG8 | OP_REG16 | OP_REG32)
15099     #define OP_IM     OP_IM32
15100         int8_t  reg; /* register, -1 if none */
15101         int8_t  reg2; /* second register, -1 if none */
15102         uint8_t shift;
15103         ExprValue e;
15104     } Operand;
15105     
15106     static const uint8_t reg_to_size[5] = {
15107         [OP_REG8] = 0,
15108         [OP_REG16] = 1,
15109         [OP_REG32] = 2,
15110     };
15111         
15112     #define WORD_PREFIX_OPCODE 0x66
15113     
15114     #define NB_TEST_OPCODES 30
15115     
15116     static const uint8_t test_bits[NB_TEST_OPCODES] = {
15117      0x00, /* o */
15118      0x01, /* no */
15119      0x02, /* b */
15120      0x02, /* c */
15121      0x02, /* nae */
15122      0x03, /* nb */
15123      0x03, /* nc */
15124      0x03, /* ae */
15125      0x04, /* e */
15126      0x04, /* z */
15127      0x05, /* ne */
15128      0x05, /* nz */
15129      0x06, /* be */
15130      0x06, /* na */
15131      0x07, /* nbe */
15132      0x07, /* a */
15133      0x08, /* s */
15134      0x09, /* ns */
15135      0x0a, /* p */
15136      0x0a, /* pe */
15137      0x0b, /* np */
15138      0x0b, /* po */
15139      0x0c, /* l */
15140      0x0c, /* nge */
15141      0x0d, /* nl */
15142      0x0d, /* ge */
15143      0x0e, /* le */
15144      0x0e, /* ng */
15145      0x0f, /* nle */
15146      0x0f, /* g */
15147     };
15148     
15149     static const ASMInstr asm_instrs[] = {
15150     #define ALT(x) x
15151     #define DEF_ASM_OP0(name, opcode)
15152     #define DEF_ASM_OP0L(name, opcode, group, instr_type) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 0 },
15153     #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 1, { op0 }},
15154     #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 2, { op0, op1 }},
15155     #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 3, { op0, op1, op2 }},
15156     // njn: inlined i386-asm.h
15157     //#include "i386-asm.h"
15158     //---------------------------------------------------------------------------
15159          DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
15160          DEF_ASM_OP0(popa, 0x61)
15161          DEF_ASM_OP0(clc, 0xf8)
15162          DEF_ASM_OP0(cld, 0xfc)
15163          DEF_ASM_OP0(cli, 0xfa)
15164          DEF_ASM_OP0(clts, 0x0f06)
15165          DEF_ASM_OP0(cmc, 0xf5)
15166          DEF_ASM_OP0(lahf, 0x9f)
15167          DEF_ASM_OP0(sahf, 0x9e)
15168          DEF_ASM_OP0(pushfl, 0x9c)
15169          DEF_ASM_OP0(popfl, 0x9d)
15170          DEF_ASM_OP0(pushf, 0x9c)
15171          DEF_ASM_OP0(popf, 0x9d)
15172          DEF_ASM_OP0(stc, 0xf9)
15173          DEF_ASM_OP0(std, 0xfd)
15174          DEF_ASM_OP0(sti, 0xfb)
15175          DEF_ASM_OP0(aaa, 0x37)
15176          DEF_ASM_OP0(aas, 0x3f)
15177          DEF_ASM_OP0(daa, 0x27)
15178          DEF_ASM_OP0(das, 0x2f)
15179          DEF_ASM_OP0(aad, 0xd50a)
15180          DEF_ASM_OP0(aam, 0xd40a)
15181          DEF_ASM_OP0(cbw, 0x6698)
15182          DEF_ASM_OP0(cwd, 0x6699)
15183          DEF_ASM_OP0(cwde, 0x98)
15184          DEF_ASM_OP0(cdq, 0x99)
15185          DEF_ASM_OP0(cbtw, 0x6698)
15186          DEF_ASM_OP0(cwtl, 0x98)
15187          DEF_ASM_OP0(cwtd, 0x6699)
15188          DEF_ASM_OP0(cltd, 0x99)
15189          DEF_ASM_OP0(int3, 0xcc)
15190          DEF_ASM_OP0(into, 0xce)
15191          DEF_ASM_OP0(iret, 0xcf)
15192          DEF_ASM_OP0(rsm, 0x0faa)
15193          DEF_ASM_OP0(hlt, 0xf4)
15194          DEF_ASM_OP0(wait, 0x9b)
15195          DEF_ASM_OP0(nop, 0x90)
15196          DEF_ASM_OP0(xlat, 0xd7)
15197     
15198          /* strings */
15199     ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
15200     ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
15201     
15202     ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
15203     ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
15204     
15205     ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
15206     ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
15207     
15208     ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
15209     ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
15210     
15211     ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
15212     ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
15213     
15214     ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
15215     ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
15216     
15217          /* bits */
15218          
15219     ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
15220     ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
15221     
15222     ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15223     ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15224     
15225     ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15226     ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15227     
15228     ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15229     ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15230     
15231     ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15232     ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15233     
15234          /* prefixes */
15235          DEF_ASM_OP0(aword, 0x67)
15236          DEF_ASM_OP0(addr16, 0x67)
15237          DEF_ASM_OP0(word, 0x66)
15238          DEF_ASM_OP0(data16, 0x66)
15239          DEF_ASM_OP0(lock, 0xf0)
15240          DEF_ASM_OP0(rep, 0xf3)
15241          DEF_ASM_OP0(repe, 0xf3)
15242          DEF_ASM_OP0(repz, 0xf3)
15243          DEF_ASM_OP0(repne, 0xf2)
15244          DEF_ASM_OP0(repnz, 0xf2)
15245                  
15246          DEF_ASM_OP0(invd, 0x0f08)
15247          DEF_ASM_OP0(wbinvd, 0x0f09)
15248          DEF_ASM_OP0(cpuid, 0x0fa2)
15249          DEF_ASM_OP0(wrmsr, 0x0f30)
15250          DEF_ASM_OP0(rdtsc, 0x0f31)
15251          DEF_ASM_OP0(rdmsr, 0x0f32)
15252          DEF_ASM_OP0(rdpmc, 0x0f33)
15253          DEF_ASM_OP0(ud2, 0x0f0b)
15254     
15255          /* NOTE: we took the same order as gas opcode definition order */
15256     ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
15257     ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
15258     ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15259     ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15260     ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
15261     ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
15262     
15263     ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
15264     ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
15265     
15266     ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
15267     ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
15268     ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
15269     ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
15270     ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
15271     ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
15272     
15273     ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
15274     ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
15275     ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
15276     ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
15277     ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
15278     
15279     ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
15280     ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
15281     ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
15282     ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
15283     ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
15284     
15285     ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
15286     ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
15287     ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
15288     
15289     ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
15290     ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
15291     ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15292     ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15293     
15294     ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
15295     ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
15296     ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
15297     ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
15298     
15299     ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
15300     ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
15301     ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
15302     ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
15303     
15304     ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
15305     
15306     ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15307     ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15308     ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15309     ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15310     ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15311     
15312          /* arith */
15313     ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
15314     ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15315     ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
15316     ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
15317     ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
15318     
15319     ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15320     ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15321     ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
15322     ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
15323     
15324     ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
15325     ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15326     ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
15327     ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15328     
15329     ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15330     ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15331     
15332     ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15333     ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15334     
15335     ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
15336     ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
15337     ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
15338     ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
15339     ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
15340     
15341     ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15342     ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
15343     ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15344     ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
15345     
15346          /* shifts */
15347     ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
15348     ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
15349     ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
15350     
15351     ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
15352     ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
15353     ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
15354     ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
15355     ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
15356     ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
15357     
15358     ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
15359     ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
15360     ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
15361     ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
15362     
15363     ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
15364     ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
15365     ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
15366     ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
15367     
15368     ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
15369     ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
15370         DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
15371         DEF_ASM_OP0(leave, 0xc9)
15372         DEF_ASM_OP0(ret, 0xc3)
15373     ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
15374         DEF_ASM_OP0(lret, 0xcb)
15375     ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
15376     
15377     ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
15378         DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
15379         DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
15380         DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
15381         DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
15382         DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
15383         DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
15384          
15385          /* float */
15386          /* specific fcomp handling */
15387     ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
15388     
15389     ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
15390     ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
15391     ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
15392     ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
15393     ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
15394     ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
15395     ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
15396     ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15397     ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15398     ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15399     ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15400     
15401          DEF_ASM_OP0(fucompp, 0xdae9)
15402          DEF_ASM_OP0(ftst, 0xd9e4)
15403          DEF_ASM_OP0(fxam, 0xd9e5)
15404          DEF_ASM_OP0(fld1, 0xd9e8)
15405          DEF_ASM_OP0(fldl2t, 0xd9e9)
15406          DEF_ASM_OP0(fldl2e, 0xd9ea)
15407          DEF_ASM_OP0(fldpi, 0xd9eb)
15408          DEF_ASM_OP0(fldlg2, 0xd9ec)
15409          DEF_ASM_OP0(fldln2, 0xd9ed)
15410          DEF_ASM_OP0(fldz, 0xd9ee)
15411     
15412          DEF_ASM_OP0(f2xm1, 0xd9f0)
15413          DEF_ASM_OP0(fyl2x, 0xd9f1)
15414          DEF_ASM_OP0(fptan, 0xd9f2)
15415          DEF_ASM_OP0(fpatan, 0xd9f3)
15416          DEF_ASM_OP0(fxtract, 0xd9f4)
15417          DEF_ASM_OP0(fprem1, 0xd9f5)
15418          DEF_ASM_OP0(fdecstp, 0xd9f6)
15419          DEF_ASM_OP0(fincstp, 0xd9f7)
15420          DEF_ASM_OP0(fprem, 0xd9f8)
15421          DEF_ASM_OP0(fyl2xp1, 0xd9f9)
15422          DEF_ASM_OP0(fsqrt, 0xd9fa)
15423          DEF_ASM_OP0(fsincos, 0xd9fb)
15424          DEF_ASM_OP0(frndint, 0xd9fc)
15425          DEF_ASM_OP0(fscale, 0xd9fd)
15426          DEF_ASM_OP0(fsin, 0xd9fe)
15427          DEF_ASM_OP0(fcos, 0xd9ff)
15428          DEF_ASM_OP0(fchs, 0xd9e0)
15429          DEF_ASM_OP0(fabs, 0xd9e1)
15430          DEF_ASM_OP0(fninit, 0xdbe3)
15431          DEF_ASM_OP0(fnclex, 0xdbe2)
15432          DEF_ASM_OP0(fnop, 0xd9d0)
15433          DEF_ASM_OP0(fwait, 0x9b)
15434     
15435         /* fp load */
15436         DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
15437         DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
15438         DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
15439     ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
15440         DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
15441         DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
15442         DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
15443         DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
15444         DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
15445         
15446         /* fp store */
15447         DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
15448         DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
15449         DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
15450         DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
15451     ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
15452         DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
15453         DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
15454         DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
15455         DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
15456         DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
15457     
15458         DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
15459         DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
15460         DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
15461         DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
15462         DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
15463     
15464         /* exchange */
15465         DEF_ASM_OP0(fxch, 0xd9c9)
15466     ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
15467     
15468         /* misc FPU */
15469         DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
15470         DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
15471     
15472         DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
15473         DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
15474         DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
15475         DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
15476         DEF_ASM_OP0(fnstsw, 0xdfe0)
15477     ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
15478     ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
15479         DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
15480     ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
15481     ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
15482         DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
15483         DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
15484         DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
15485         DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
15486         DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
15487         DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
15488         DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
15489         DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
15490         DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
15491         DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
15492         DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
15493     
15494         /* segments */
15495         DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
15496         DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
15497         DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
15498         DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
15499         DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
15500         DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
15501     ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
15502         DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
15503         DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
15504         DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
15505         DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
15506         DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
15507         DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
15508         DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
15509         DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
15510     
15511         /* 486 */
15512         DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
15513     ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
15514     ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
15515         DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
15516     
15517         DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
15518         DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
15519     
15520         /* pentium */
15521         DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
15522         
15523         /* pentium pro */
15524         ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
15525     
15526         DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15527         DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15528         DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15529         DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15530         DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15531         DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15532         DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15533         DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15534     
15535         DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15536         DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15537         DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15538         DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15539     
15540         /* mmx */
15541         DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
15542         DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
15543     ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
15544         DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15545     ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
15546         DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15547         DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15548         DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15549         DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15550         DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15551         DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15552         DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15553         DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15554         DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15555         DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15556         DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15557         DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15558         DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15559         DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15560         DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15561         DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15562         DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15563         DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15564         DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15565         DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15566         DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15567         DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15568         DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15569     ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
15570         DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15571     ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
15572         DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15573     ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
15574         DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15575     ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
15576         DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15577     ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
15578         DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15579     ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
15580         DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15581     ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
15582         DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15583     ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
15584         DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15585         DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15586         DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15587         DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15588         DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15589         DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15590         DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15591         DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15592         DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15593         DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15594         DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15595         DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15596         DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15597         DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15598     
15599     #undef ALT
15600     #undef DEF_ASM_OP0
15601     #undef DEF_ASM_OP0L
15602     #undef DEF_ASM_OP1
15603     #undef DEF_ASM_OP2
15604     #undef DEF_ASM_OP3
15605     //---------------------------------------------------------------------------
15606     
15607         /* last operation */
15608         { 0, },
15609     };
15610     
15611     static const uint16_t op0_codes[] = {
15612     #define ALT(x)
15613     #define DEF_ASM_OP0(x, opcode) opcode,
15614     #define DEF_ASM_OP0L(name, opcode, group, instr_type)
15615     #define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
15616     #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
15617     #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
15618     // njn: inlined i386-asm.h
15619     //#include "i386-asm.h"
15620     //---------------------------------------------------------------------------
15621          DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
15622          DEF_ASM_OP0(popa, 0x61)
15623          DEF_ASM_OP0(clc, 0xf8)
15624          DEF_ASM_OP0(cld, 0xfc)
15625          DEF_ASM_OP0(cli, 0xfa)
15626          DEF_ASM_OP0(clts, 0x0f06)
15627          DEF_ASM_OP0(cmc, 0xf5)
15628          DEF_ASM_OP0(lahf, 0x9f)
15629          DEF_ASM_OP0(sahf, 0x9e)
15630          DEF_ASM_OP0(pushfl, 0x9c)
15631          DEF_ASM_OP0(popfl, 0x9d)
15632          DEF_ASM_OP0(pushf, 0x9c)
15633          DEF_ASM_OP0(popf, 0x9d)
15634          DEF_ASM_OP0(stc, 0xf9)
15635          DEF_ASM_OP0(std, 0xfd)
15636          DEF_ASM_OP0(sti, 0xfb)
15637          DEF_ASM_OP0(aaa, 0x37)
15638          DEF_ASM_OP0(aas, 0x3f)
15639          DEF_ASM_OP0(daa, 0x27)
15640          DEF_ASM_OP0(das, 0x2f)
15641          DEF_ASM_OP0(aad, 0xd50a)
15642          DEF_ASM_OP0(aam, 0xd40a)
15643          DEF_ASM_OP0(cbw, 0x6698)
15644          DEF_ASM_OP0(cwd, 0x6699)
15645          DEF_ASM_OP0(cwde, 0x98)
15646          DEF_ASM_OP0(cdq, 0x99)
15647          DEF_ASM_OP0(cbtw, 0x6698)
15648          DEF_ASM_OP0(cwtl, 0x98)
15649          DEF_ASM_OP0(cwtd, 0x6699)
15650          DEF_ASM_OP0(cltd, 0x99)
15651          DEF_ASM_OP0(int3, 0xcc)
15652          DEF_ASM_OP0(into, 0xce)
15653          DEF_ASM_OP0(iret, 0xcf)
15654          DEF_ASM_OP0(rsm, 0x0faa)
15655          DEF_ASM_OP0(hlt, 0xf4)
15656          DEF_ASM_OP0(wait, 0x9b)
15657          DEF_ASM_OP0(nop, 0x90)
15658          DEF_ASM_OP0(xlat, 0xd7)
15659     
15660          /* strings */
15661     ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
15662     ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
15663     
15664     ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
15665     ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
15666     
15667     ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
15668     ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
15669     
15670     ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
15671     ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
15672     
15673     ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
15674     ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
15675     
15676     ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
15677     ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
15678     
15679          /* bits */
15680          
15681     ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
15682     ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
15683     
15684     ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15685     ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15686     
15687     ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15688     ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15689     
15690     ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15691     ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15692     
15693     ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15694     ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15695     
15696          /* prefixes */
15697          DEF_ASM_OP0(aword, 0x67)
15698          DEF_ASM_OP0(addr16, 0x67)
15699          DEF_ASM_OP0(word, 0x66)
15700          DEF_ASM_OP0(data16, 0x66)
15701          DEF_ASM_OP0(lock, 0xf0)
15702          DEF_ASM_OP0(rep, 0xf3)
15703          DEF_ASM_OP0(repe, 0xf3)
15704          DEF_ASM_OP0(repz, 0xf3)
15705          DEF_ASM_OP0(repne, 0xf2)
15706          DEF_ASM_OP0(repnz, 0xf2)
15707                  
15708          DEF_ASM_OP0(invd, 0x0f08)
15709          DEF_ASM_OP0(wbinvd, 0x0f09)
15710          DEF_ASM_OP0(cpuid, 0x0fa2)
15711          DEF_ASM_OP0(wrmsr, 0x0f30)
15712          DEF_ASM_OP0(rdtsc, 0x0f31)
15713          DEF_ASM_OP0(rdmsr, 0x0f32)
15714          DEF_ASM_OP0(rdpmc, 0x0f33)
15715          DEF_ASM_OP0(ud2, 0x0f0b)
15716     
15717          /* NOTE: we took the same order as gas opcode definition order */
15718     ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
15719     ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
15720     ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15721     ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15722     ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
15723     ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
15724     
15725     ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
15726     ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
15727     
15728     ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
15729     ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
15730     ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
15731     ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
15732     ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
15733     ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
15734     
15735     ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
15736     ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
15737     ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
15738     ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
15739     ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
15740     
15741     ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
15742     ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
15743     ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
15744     ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
15745     ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
15746     
15747     ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
15748     ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
15749     ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
15750     
15751     ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
15752     ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
15753     ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15754     ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15755     
15756     ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
15757     ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
15758     ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
15759     ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
15760     
15761     ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
15762     ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
15763     ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
15764     ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
15765     
15766     ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
15767     
15768     ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15769     ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15770     ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15771     ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15772     ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15773     
15774          /* arith */
15775     ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
15776     ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15777     ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
15778     ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
15779     ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
15780     
15781     ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15782     ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15783     ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
15784     ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
15785     
15786     ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
15787     ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15788     ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
15789     ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15790     
15791     ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15792     ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15793     
15794     ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15795     ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15796     
15797     ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
15798     ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
15799     ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
15800     ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
15801     ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
15802     
15803     ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15804     ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
15805     ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15806     ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
15807     
15808          /* shifts */
15809     ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
15810     ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
15811     ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
15812     
15813     ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
15814     ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
15815     ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
15816     ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
15817     ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
15818     ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
15819     
15820     ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
15821     ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
15822     ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
15823     ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
15824     
15825     ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
15826     ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
15827     ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
15828     ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
15829     
15830     ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
15831     ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
15832         DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
15833         DEF_ASM_OP0(leave, 0xc9)
15834         DEF_ASM_OP0(ret, 0xc3)
15835     ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
15836         DEF_ASM_OP0(lret, 0xcb)
15837     ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
15838     
15839     ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
15840         DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
15841         DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
15842         DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
15843         DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
15844         DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
15845         DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
15846          
15847          /* float */
15848          /* specific fcomp handling */
15849     ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
15850     
15851     ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
15852     ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
15853     ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
15854     ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
15855     ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
15856     ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
15857     ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
15858     ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15859     ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15860     ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15861     ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15862     
15863          DEF_ASM_OP0(fucompp, 0xdae9)
15864          DEF_ASM_OP0(ftst, 0xd9e4)
15865          DEF_ASM_OP0(fxam, 0xd9e5)
15866          DEF_ASM_OP0(fld1, 0xd9e8)
15867          DEF_ASM_OP0(fldl2t, 0xd9e9)
15868          DEF_ASM_OP0(fldl2e, 0xd9ea)
15869          DEF_ASM_OP0(fldpi, 0xd9eb)
15870          DEF_ASM_OP0(fldlg2, 0xd9ec)
15871          DEF_ASM_OP0(fldln2, 0xd9ed)
15872          DEF_ASM_OP0(fldz, 0xd9ee)
15873     
15874          DEF_ASM_OP0(f2xm1, 0xd9f0)
15875          DEF_ASM_OP0(fyl2x, 0xd9f1)
15876          DEF_ASM_OP0(fptan, 0xd9f2)
15877          DEF_ASM_OP0(fpatan, 0xd9f3)
15878          DEF_ASM_OP0(fxtract, 0xd9f4)
15879          DEF_ASM_OP0(fprem1, 0xd9f5)
15880          DEF_ASM_OP0(fdecstp, 0xd9f6)
15881          DEF_ASM_OP0(fincstp, 0xd9f7)
15882          DEF_ASM_OP0(fprem, 0xd9f8)
15883          DEF_ASM_OP0(fyl2xp1, 0xd9f9)
15884          DEF_ASM_OP0(fsqrt, 0xd9fa)
15885          DEF_ASM_OP0(fsincos, 0xd9fb)
15886          DEF_ASM_OP0(frndint, 0xd9fc)
15887          DEF_ASM_OP0(fscale, 0xd9fd)
15888          DEF_ASM_OP0(fsin, 0xd9fe)
15889          DEF_ASM_OP0(fcos, 0xd9ff)
15890          DEF_ASM_OP0(fchs, 0xd9e0)
15891          DEF_ASM_OP0(fabs, 0xd9e1)
15892          DEF_ASM_OP0(fninit, 0xdbe3)
15893          DEF_ASM_OP0(fnclex, 0xdbe2)
15894          DEF_ASM_OP0(fnop, 0xd9d0)
15895          DEF_ASM_OP0(fwait, 0x9b)
15896     
15897         /* fp load */
15898         DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
15899         DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
15900         DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
15901     ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
15902         DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
15903         DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
15904         DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
15905         DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
15906         DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
15907         
15908         /* fp store */
15909         DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
15910         DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
15911         DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
15912         DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
15913     ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
15914         DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
15915         DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
15916         DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
15917         DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
15918         DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
15919     
15920         DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
15921         DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
15922         DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
15923         DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
15924         DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
15925     
15926         /* exchange */
15927         DEF_ASM_OP0(fxch, 0xd9c9)
15928     ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
15929     
15930         /* misc FPU */
15931         DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
15932         DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
15933     
15934         DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
15935         DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
15936         DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
15937         DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
15938         DEF_ASM_OP0(fnstsw, 0xdfe0)
15939     ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
15940     ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
15941         DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
15942     ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
15943     ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
15944         DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
15945         DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
15946         DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
15947         DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
15948         DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
15949         DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
15950         DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
15951         DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
15952         DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
15953         DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
15954         DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
15955     
15956         /* segments */
15957         DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
15958         DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
15959         DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
15960         DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
15961         DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
15962         DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
15963     ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
15964         DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
15965         DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
15966         DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
15967         DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
15968         DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
15969         DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
15970         DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
15971         DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
15972     
15973         /* 486 */
15974         DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
15975     ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
15976     ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
15977         DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
15978     
15979         DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
15980         DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
15981     
15982         /* pentium */
15983         DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
15984         
15985         /* pentium pro */
15986         ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
15987     
15988         DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15989         DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15990         DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15991         DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15992         DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15993         DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15994         DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15995         DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15996     
15997         DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15998         DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15999         DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
16000         DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
16001     
16002         /* mmx */
16003         DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
16004         DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
16005     ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
16006         DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16007     ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
16008         DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16009         DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16010         DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16011         DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16012         DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16013         DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16014         DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16015         DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16016         DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16017         DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16018         DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16019         DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16020         DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16021         DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16022         DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16023         DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16024         DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16025         DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16026         DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16027         DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16028         DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16029         DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16030         DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16031     ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
16032         DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16033     ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
16034         DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16035     ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
16036         DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16037     ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
16038         DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16039     ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
16040         DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16041     ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
16042         DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16043     ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
16044         DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16045     ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
16046         DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16047         DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16048         DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16049         DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16050         DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16051         DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16052         DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16053         DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16054         DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16055         DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16056         DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16057         DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16058         DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16059         DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16060     
16061     #undef ALT
16062     #undef DEF_ASM_OP0
16063     #undef DEF_ASM_OP0L
16064     #undef DEF_ASM_OP1
16065     #undef DEF_ASM_OP2
16066     #undef DEF_ASM_OP3
16067     //---------------------------------------------------------------------------
16068     };
16069     
16070     static inline int get_reg_shift(TCCState *s1)
16071     {
16072         int shift, v;
16073     
16074         v = asm_int_expr(s1);
16075         switch(v) {
16076         case 1:
16077             shift = 0;
16078             break;
16079         case 2:
16080             shift = 1;
16081             break;
16082         case 4:
16083             shift = 2;
16084             break;
16085         case 8:
16086             shift = 3;
16087             break;
16088         default:
16089             expect("1, 2, 4 or 8 constant");
16090             shift = 0;
16091             break;
16092         }
16093         return shift;
16094     }
16095     
16096     static int asm_parse_reg(void)
16097     {
16098         int reg;
16099         if (tok != '%')
16100             goto error_32;
16101         next();
16102         if (tok >= TOK_ASM_eax && tok <= TOK_ASM_edi) {
16103             reg = tok - TOK_ASM_eax;
16104             next();
16105             return reg;
16106         } else {
16107         error_32:
16108             expect("32 bit register");
16109             return 0;
16110         }
16111     }
16112     
16113     static void parse_operand(TCCState *s1, Operand *op)
16114     {
16115         ExprValue e;
16116         int reg, indir;
16117         const char *p;
16118     
16119         indir = 0;
16120         if (tok == '*') {
16121             next();
16122             indir = OP_INDIR;
16123         }
16124     
16125         if (tok == '%') {
16126             next();
16127             if (tok >= TOK_ASM_al && tok <= TOK_ASM_db7) {
16128                 reg = tok - TOK_ASM_al;
16129                 op->type = 1 << (reg >> 3); /* WARNING: do not change constant order */
16130                 op->reg = reg & 7;
16131                 if ((op->type & OP_REG) && op->reg == TREG_EAX)
16132                     op->type |= OP_EAX;
16133                 else if (op->type == OP_REG8 && op->reg == TREG_ECX)
16134                     op->type |= OP_CL;
16135                 else if (op->type == OP_REG16 && op->reg == TREG_EDX)
16136                     op->type |= OP_DX;
16137             } else if (tok >= TOK_ASM_dr0 && tok <= TOK_ASM_dr7) {
16138                 op->type = OP_DB;
16139                 op->reg = tok - TOK_ASM_dr0;
16140             } else if (tok >= TOK_ASM_es && tok <= TOK_ASM_gs) {
16141                 op->type = OP_SEG;
16142                 op->reg = tok - TOK_ASM_es;
16143             } else if (tok == TOK_ASM_st) {
16144                 op->type = OP_ST;
16145                 op->reg = 0;
16146                 next();
16147                 if (tok == '(') {
16148                     next();
16149                     if (tok != TOK_PPNUM)
16150                         goto reg_error;
16151                     p = tokc.cstr->data;
16152                     reg = p[0] - '0';
16153                     if ((unsigned)reg >= 8 || p[1] != '\0')
16154                         goto reg_error;
16155                     op->reg = reg;
16156                     next();
16157                     skip(')');
16158                 }
16159                 if (op->reg == 0)
16160                     op->type |= OP_ST0;
16161                 goto no_skip;
16162             } else {
16163             reg_error:
16164                 error("unknown register");
16165             }
16166             next();
16167         no_skip: ;
16168         } else if (tok == '$') {
16169             /* constant value */
16170             next();
16171             asm_expr(s1, &e);
16172             op->type = OP_IM32;
16173             op->e.v = e.v;
16174             op->e.sym = e.sym;
16175             if (!op->e.sym) {
16176                 if (op->e.v == (uint8_t)op->e.v)
16177                     op->type |= OP_IM8;
16178                 if (op->e.v == (int8_t)op->e.v)
16179                     op->type |= OP_IM8S;
16180                 if (op->e.v == (uint16_t)op->e.v)
16181                     op->type |= OP_IM16;
16182             }
16183         } else {
16184             /* address(reg,reg2,shift) with all variants */
16185             op->type = OP_EA;
16186             op->reg = -1;
16187             op->reg2 = -1;
16188             op->shift = 0;
16189             if (tok != '(') {
16190                 asm_expr(s1, &e);
16191                 op->e.v = e.v;
16192                 op->e.sym = e.sym;
16193             } else {
16194                 op->e.v = 0;
16195                 op->e.sym = NULL;
16196             }
16197             if (tok == '(') {
16198                 next();
16199                 if (tok != ',') {
16200                     op->reg = asm_parse_reg();
16201                 }
16202                 if (tok == ',') {
16203                     next();
16204                     if (tok != ',') {
16205                         op->reg2 = asm_parse_reg();
16206                     } 
16207                     skip(',');
16208                     op->shift = get_reg_shift(s1);
16209                 }
16210                 skip(')');
16211             }
16212             if (op->reg == -1 && op->reg2 == -1)
16213                 op->type |= OP_ADDR;
16214         }
16215         op->type |= indir;
16216     }
16217     
16218     /* XXX: unify with C code output ? */
16219     static void gen_expr32(ExprValue *pe)
16220     {
16221         if (pe->sym)
16222             greloc(cur_text_section, pe->sym, ind, R_386_32);
16223         gen_le32(pe->v);
16224     }
16225     
16226     /* XXX: unify with C code output ? */
16227     static void gen_disp32(ExprValue *pe)
16228     {
16229         Sym *sym;
16230         sym = pe->sym;
16231         if (sym) {
16232             if (sym->r == cur_text_section->sh_num) {
16233                 /* same section: we can output an absolute value. Note
16234                    that the TCC compiler behaves differently here because
16235                    it always outputs a relocation to ease (future) code
16236                    elimination in the linker */
16237                 gen_le32(pe->v + (long)sym->next - ind - 4);
16238             } else {
16239                 greloc(cur_text_section, sym, ind, R_386_PC32);
16240                 gen_le32(pe->v - 4);
16241             }
16242         } else {
16243             /* put an empty PC32 relocation */
16244             put_elf_reloc(symtab_section, cur_text_section, 
16245                           ind, R_386_PC32, 0);
16246             gen_le32(pe->v - 4);
16247         }
16248     }
16249     
16250     
16251     static void gen_le16(int v)
16252     {
16253         g(v);
16254         g(v >> 8);
16255     }
16256     
16257     /* generate the modrm operand */
16258     static inline void asm_modrm(int reg, Operand *op)
16259     {
16260         int mod, reg1, reg2, sib_reg1;
16261     
16262         if (op->type & (OP_REG | OP_MMX | OP_SSE)) {
16263             g(0xc0 + (reg << 3) + op->reg);
16264         } else if (op->reg == -1 && op->reg2 == -1) {
16265             /* displacement only */
16266             g(0x05 + (reg << 3));
16267             gen_expr32(&op->e);
16268         } else {
16269             sib_reg1 = op->reg;
16270             /* fist compute displacement encoding */
16271             if (sib_reg1 == -1) {
16272                 sib_reg1 = 5;
16273                 mod = 0x00;
16274             } else if (op->e.v == 0 && !op->e.sym && op->reg != 5) {
16275                 mod = 0x00;
16276             } else if (op->e.v == (int8_t)op->e.v && !op->e.sym) {
16277                 mod = 0x40;
16278             } else {
16279                 mod = 0x80;
16280             }
16281             /* compute if sib byte needed */
16282             reg1 = op->reg;
16283             if (op->reg2 != -1)
16284                 reg1 = 4;
16285             g(mod + (reg << 3) + reg1);
16286             if (reg1 == 4) {
16287                 /* add sib byte */
16288                 reg2 = op->reg2;
16289                 if (reg2 == -1)
16290                     reg2 = 4; /* indicate no index */
16291                 g((op->shift << 6) + (reg2 << 3) + sib_reg1);
16292             }
16293     
16294             /* add offset */
16295             if (mod == 0x40) {
16296                 g(op->e.v);
16297             } else if (mod == 0x80 || op->reg == -1) {
16298                 gen_expr32(&op->e);
16299             }
16300         }
16301     }
16302     
16303     static void asm_opcode(TCCState *s1, int opcode)
16304     {
16305         const ASMInstr *pa;
16306         int i, modrm_index, reg, v, op1, is_short_jmp;
16307         int nb_ops, s, ss;
16308         Operand ops[MAX_OPERANDS], *pop;
16309         int op_type[3]; /* decoded op type */
16310     
16311         /* get operands */
16312         pop = ops;
16313         nb_ops = 0;
16314         for(;;) {
16315             if (tok == ';' || tok == TOK_LINEFEED)
16316                 break;
16317             if (nb_ops >= MAX_OPERANDS) {
16318                 error("incorrect number of operands");
16319             }
16320             parse_operand(s1, pop);
16321             pop++;
16322             nb_ops++;
16323             if (tok != ',')
16324                 break;
16325             next();
16326         }
16327     
16328         is_short_jmp = 0;
16329         s = 0; /* avoid warning */
16330         
16331         /* optimize matching by using a lookup table (no hashing is needed
16332            !) */
16333         for(pa = asm_instrs; pa->sym != 0; pa++) {
16334             s = 0;
16335             if (pa->instr_type & OPC_FARITH) {
16336                 v = opcode - pa->sym;
16337                 if (!((unsigned)v < 8 * 6 && (v % 6) == 0))
16338                     continue;
16339             } else if (pa->instr_type & OPC_ARITH) {
16340                 if (!(opcode >= pa->sym && opcode < pa->sym + 8 * 4))
16341                     continue;
16342                 goto compute_size;
16343             } else if (pa->instr_type & OPC_SHIFT) {
16344                 if (!(opcode >= pa->sym && opcode < pa->sym + 7 * 4))
16345                     continue;
16346                 goto compute_size;
16347             } else if (pa->instr_type & OPC_TEST) {
16348                 if (!(opcode >= pa->sym && opcode < pa->sym + NB_TEST_OPCODES))
16349                     continue;
16350             } else if (pa->instr_type & OPC_B) {
16351                 if (!(opcode >= pa->sym && opcode <= pa->sym + 3))
16352                     continue;
16353             compute_size:
16354                 s = (opcode - pa->sym) & 3;
16355             } else if (pa->instr_type & OPC_WL) {
16356                 if (!(opcode >= pa->sym && opcode <= pa->sym + 2))
16357                     continue;
16358                 s = opcode - pa->sym + 1;
16359             } else {
16360                 if (pa->sym != opcode)
16361                     continue;
16362             }
16363             if (pa->nb_ops != nb_ops)
16364                 continue;
16365             /* now decode and check each operand */
16366             for(i = 0; i < nb_ops; i++) {
16367                 int op1, op2;
16368                 op1 = pa->op_type[i];
16369                 op2 = op1 & 0x1f;
16370                 switch(op2) {
16371                 case OPT_IM:
16372                     v = OP_IM8 | OP_IM16 | OP_IM32;
16373                     break;
16374                 case OPT_REG:
16375                     v = OP_REG8 | OP_REG16 | OP_REG32;
16376                     break;
16377                 case OPT_REGW:
16378                     v = OP_REG16 | OP_REG32;
16379                     break;
16380                 case OPT_IMW:
16381                     v = OP_IM16 | OP_IM32;
16382                     break;
16383                 default:
16384                     v = 1 << op2;
16385                     break;
16386                 }
16387                 if (op1 & OPT_EA)
16388                     v |= OP_EA;
16389                 op_type[i] = v;
16390                 if ((ops[i].type & v) == 0)
16391                     goto next;
16392             }
16393             /* all is matching ! */
16394             break;
16395         next: ;
16396         }
16397         if (pa->sym == 0) {
16398             if (opcode >= TOK_ASM_pusha && opcode <= TOK_ASM_emms) {
16399                 int b;
16400                 b = op0_codes[opcode - TOK_ASM_pusha];
16401                 if (b & 0xff00) 
16402                     g(b >> 8);
16403                 g(b);
16404                 return;
16405             } else {
16406                 error("unknown opcode '%s'", 
16407                       get_tok_str(opcode, NULL));
16408             }
16409         }
16410         /* if the size is unknown, then evaluate it (OPC_B or OPC_WL case) */
16411         if (s == 3) {
16412             for(i = 0; s == 3 && i < nb_ops; i++) {
16413                 if ((ops[i].type & OP_REG) && !(op_type[i] & (OP_CL | OP_DX)))
16414                     s = reg_to_size[ops[i].type & OP_REG];
16415             }
16416             if (s == 3) {
16417                 if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) && 
16418                     (ops[0].type & (OP_SEG | OP_IM8S | OP_IM32)))
16419                     s = 2;
16420                 else
16421                     error("cannot infer opcode suffix");
16422             }
16423         }
16424     
16425         /* generate data16 prefix if needed */
16426         ss = s;
16427         if (s == 1 || (pa->instr_type & OPC_D16))
16428             g(WORD_PREFIX_OPCODE);
16429         else if (s == 2)
16430             s = 1;
16431         /* now generates the operation */
16432         if (pa->instr_type & OPC_FWAIT)
16433             g(0x9b);
16434     
16435         v = pa->opcode;
16436         if (v == 0x69 || v == 0x69) {
16437             /* kludge for imul $im, %reg */
16438             nb_ops = 3;
16439             ops[2] = ops[1];
16440         } else if (v == 0xcd && ops[0].e.v == 3 && !ops[0].e.sym) {
16441             v--; /* int $3 case */
16442             nb_ops = 0;
16443         } else if ((v == 0x06 || v == 0x07)) {
16444             if (ops[0].reg >= 4) {
16445                 /* push/pop %fs or %gs */
16446                 v = 0x0fa0 + (v - 0x06) + ((ops[0].reg - 4) << 3);
16447             } else {
16448                 v += ops[0].reg << 3;
16449             }
16450             nb_ops = 0;
16451         } else if (v <= 0x05) {
16452             /* arith case */
16453             v += ((opcode - TOK_ASM_addb) >> 2) << 3;
16454         } else if ((pa->instr_type & (OPC_FARITH | OPC_MODRM)) == OPC_FARITH) {
16455             /* fpu arith case */
16456             v += ((opcode - pa->sym) / 6) << 3;
16457         }
16458         if (pa->instr_type & OPC_REG) {
16459             for(i = 0; i < nb_ops; i++) {
16460                 if (op_type[i] & (OP_REG | OP_ST)) {
16461                     v += ops[i].reg;
16462                     break;
16463                 }
16464             }
16465             /* mov $im, %reg case */
16466             if (pa->opcode == 0xb0 && s >= 1)
16467                 v += 7;
16468         }
16469         if (pa->instr_type & OPC_B)
16470             v += s;
16471         if (pa->instr_type & OPC_TEST)
16472             v += test_bits[opcode - pa->sym]; 
16473         if (pa->instr_type & OPC_SHORTJMP) {
16474             Sym *sym;
16475             int jmp_disp;
16476     
16477             /* see if we can really generate the jump with a byte offset */
16478             sym = ops[0].e.sym;
16479             if (!sym)
16480                 goto no_short_jump;
16481             if (sym->r != cur_text_section->sh_num)
16482                 goto no_short_jump;
16483             jmp_disp = ops[0].e.v + (long)sym->next - ind - 2;
16484             if (jmp_disp == (int8_t)jmp_disp) {
16485                 /* OK to generate jump */
16486                 is_short_jmp = 1;
16487                 ops[0].e.v = jmp_disp;
16488             } else {
16489             no_short_jump:
16490                 if (pa->instr_type & OPC_JMP) {
16491                     /* long jump will be allowed. need to modify the
16492                        opcode slightly */
16493                     if (v == 0xeb)
16494                         v = 0xe9;
16495                     else 
16496                         v += 0x0f10;
16497                 } else {
16498                     error("invalid displacement");
16499                 }
16500             }
16501         }
16502         op1 = v >> 8;
16503         if (op1)
16504             g(op1);
16505         g(v);
16506             
16507         /* search which operand will used for modrm */
16508         modrm_index = 0;
16509         if (pa->instr_type & OPC_SHIFT) {
16510             reg = (opcode - pa->sym) >> 2; 
16511             if (reg == 6)
16512                 reg = 7;
16513         } else if (pa->instr_type & OPC_ARITH) {
16514             reg = (opcode - pa->sym) >> 2;
16515         } else if (pa->instr_type & OPC_FARITH) {
16516             reg = (opcode - pa->sym) / 6;
16517         } else {
16518             reg = (pa->instr_type >> OPC_GROUP_SHIFT) & 7;
16519         }
16520         if (pa->instr_type & OPC_MODRM) {
16521             /* first look for an ea operand */
16522             for(i = 0;i < nb_ops; i++) {
16523                 if (op_type[i] & OP_EA)
16524                     goto modrm_found;
16525             }
16526             /* then if not found, a register or indirection (shift instructions) */
16527             for(i = 0;i < nb_ops; i++) {
16528                 if (op_type[i] & (OP_REG | OP_MMX | OP_SSE | OP_INDIR))
16529                     goto modrm_found;
16530             }
16531     #ifdef ASM_DEBUG
16532             error("bad op table");
16533     #endif      
16534         modrm_found:
16535             modrm_index = i;
16536             /* if a register is used in another operand then it is
16537                used instead of group */
16538             for(i = 0;i < nb_ops; i++) {
16539                 v = op_type[i];
16540                 if (i != modrm_index && 
16541                     (v & (OP_REG | OP_MMX | OP_SSE | OP_CR | OP_TR | OP_DB | OP_SEG))) {
16542                     reg = ops[i].reg;
16543                     break;
16544                 }
16545             }
16546     
16547             asm_modrm(reg, &ops[modrm_index]);
16548         }
16549     
16550         /* emit constants */
16551         if (pa->opcode == 0x9a || pa->opcode == 0xea) {
16552             /* ljmp or lcall kludge */
16553             gen_expr32(&ops[1].e);
16554             if (ops[0].e.sym)
16555                 error("cannot relocate");
16556             gen_le16(ops[0].e.v);
16557         } else {
16558             for(i = 0;i < nb_ops; i++) {
16559                 v = op_type[i];
16560                 if (v & (OP_IM8 | OP_IM16 | OP_IM32 | OP_IM8S | OP_ADDR)) {
16561                     /* if multiple sizes are given it means we must look
16562                        at the op size */
16563                     if (v == (OP_IM8 | OP_IM16 | OP_IM32) ||
16564                         v == (OP_IM16 | OP_IM32)) {
16565                         if (ss == 0)
16566                             v = OP_IM8;
16567                         else if (ss == 1)
16568                             v = OP_IM16;
16569                         else
16570                             v = OP_IM32;
16571                     }
16572                     if (v & (OP_IM8 | OP_IM8S)) {
16573                         if (ops[i].e.sym)
16574                             goto error_relocate;
16575                         g(ops[i].e.v);
16576                     } else if (v & OP_IM16) {
16577                         if (ops[i].e.sym) {
16578                         error_relocate:
16579                             error("cannot relocate");
16580                         }
16581                         gen_le16(ops[i].e.v);
16582                     } else {
16583                         if (pa->instr_type & (OPC_JMP | OPC_SHORTJMP)) {
16584                             if (is_short_jmp)
16585                                 g(ops[i].e.v);
16586                             else
16587                                 gen_disp32(&ops[i].e);
16588                         } else {
16589                             gen_expr32(&ops[i].e);
16590                         }
16591                     }
16592                 }
16593             }
16594         }
16595     }
16596     
16597     #define NB_SAVED_REGS 3
16598     #define NB_ASM_REGS 8
16599     
16600     /* return the constraint priority (we allocate first the lowest
16601        numbered constraints) */
16602     static inline int constraint_priority(const char *str)
16603     {
16604         int priority, c, pr;
16605     
16606         /* we take the lowest priority */
16607         priority = 0;
16608         for(;;) {
16609             c = *str;
16610             if (c == '\0')
16611                 break;
16612             str++;
16613             switch(c) {
16614             case 'A':
16615                 pr = 0;
16616                 break;
16617             case 'a':
16618             case 'b':
16619             case 'c':
16620             case 'd':
16621             case 'S':
16622             case 'D':
16623                 pr = 1;
16624                 break;
16625             case 'q':
16626                 pr = 2;
16627                 break;
16628             case 'r':
16629                 pr = 3;
16630                 break;
16631             case 'N':
16632             case 'M':
16633             case 'I':
16634             case 'i':
16635             case 'm':
16636             case 'g':
16637                 pr = 4;
16638                 break;
16639             default:
16640                 error("unknown constraint '%c'", c);
16641                 pr = 0;
16642             }
16643             if (pr > priority)
16644                 priority = pr;
16645         }
16646         return priority;
16647     }
16648     
16649     static const char *skip_constraint_modifiers(const char *p)
16650     {
16651         while (*p == '=' || *p == '&' || *p == '+' || *p == '%')
16652             p++;
16653         return p;
16654     }
16655     
16656     #define REG_OUT_MASK 0x01
16657     #define REG_IN_MASK  0x02
16658     
16659     #define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask)
16660     
16661     static void asm_compute_constraints(ASMOperand *operands, 
16662                                         int nb_operands, int nb_outputs, 
16663                                         const uint8_t *clobber_regs,
16664                                         int *pout_reg)
16665     {
16666         ASMOperand *op;
16667         int sorted_op[MAX_ASM_OPERANDS];
16668         int i, j, k, p1, p2, tmp, reg, c, reg_mask;
16669         const char *str;
16670         uint8_t regs_allocated[NB_ASM_REGS];
16671         
16672         /* init fields */
16673         for(i=0;i<nb_operands;i++) {
16674             op = &operands[i];
16675             op->input_index = -1;
16676             op->ref_index = -1;
16677             op->reg = -1;
16678             op->is_memory = 0;
16679             op->is_rw = 0;
16680         }
16681         /* compute constraint priority and evaluate references to output
16682            constraints if input constraints */
16683         for(i=0;i<nb_operands;i++) {
16684             op = &operands[i];
16685             str = op->constraint;
16686             str = skip_constraint_modifiers(str);
16687             if (isnum(*str) || *str == '[') {
16688                 /* this is a reference to another constraint */
16689                 k = find_constraint(operands, nb_operands, str, NULL);
16690                 if ((unsigned)k >= i || i < nb_outputs)
16691                     error("invalid reference in constraint %d ('%s')",
16692                           i, str);
16693                 op->ref_index = k;
16694                 if (operands[k].input_index >= 0)
16695                     error("cannot reference twice the same operand");
16696                 operands[k].input_index = i;
16697                 op->priority = 5;
16698             } else {
16699                 op->priority = constraint_priority(str);
16700             }
16701         }
16702         
16703         /* sort operands according to their priority */
16704         for(i=0;i<nb_operands;i++)
16705             sorted_op[i] = i;
16706         for(i=0;i<nb_operands - 1;i++) {
16707             for(j=i+1;j<nb_operands;j++) {
16708                 p1 = operands[sorted_op[i]].priority; 
16709                 p2 = operands[sorted_op[j]].priority;
16710                 if (p2 < p1) {
16711                     tmp = sorted_op[i];
16712                     sorted_op[i] = sorted_op[j];
16713                     sorted_op[j] = tmp;
16714                 }
16715             }
16716         }
16717     
16718         for(i = 0;i < NB_ASM_REGS; i++) {
16719             if (clobber_regs[i])
16720                 regs_allocated[i] = REG_IN_MASK | REG_OUT_MASK;
16721             else
16722                 regs_allocated[i] = 0;
16723         }
16724         /* esp cannot be used */
16725         regs_allocated[4] = REG_IN_MASK | REG_OUT_MASK; 
16726         /* ebp cannot be used yet */
16727         regs_allocated[5] = REG_IN_MASK | REG_OUT_MASK; 
16728     
16729         /* allocate registers and generate corresponding asm moves */
16730         for(i=0;i<nb_operands;i++) {
16731             j = sorted_op[i];
16732             op = &operands[j];
16733             str = op->constraint;
16734             /* no need to allocate references */
16735             if (op->ref_index >= 0)
16736                 continue;
16737             /* select if register is used for output, input or both */
16738             if (op->input_index >= 0) {
16739                 reg_mask = REG_IN_MASK | REG_OUT_MASK;
16740             } else if (j < nb_outputs) {
16741                 reg_mask = REG_OUT_MASK;
16742             } else {
16743                 reg_mask = REG_IN_MASK;
16744             }
16745         try_next:
16746             c = *str++;
16747             switch(c) {
16748             case '=':
16749                 goto try_next;
16750             case '+':
16751                 op->is_rw = 1;
16752                 /* FALL THRU */
16753             case '&':
16754                 if (j >= nb_outputs)
16755                     error("'%c' modifier can only be applied to outputs", c);
16756                 reg_mask = REG_IN_MASK | REG_OUT_MASK;
16757                 goto try_next;
16758             case 'A':
16759                 /* allocate both eax and edx */
16760                 if (is_reg_allocated(TREG_EAX) || 
16761                     is_reg_allocated(TREG_EDX))
16762                     goto try_next;
16763                 op->is_llong = 1;
16764                 op->reg = TREG_EAX;
16765                 regs_allocated[TREG_EAX] |= reg_mask;
16766                 regs_allocated[TREG_EDX] |= reg_mask;
16767                 break;
16768             case 'a':
16769                 reg = TREG_EAX;
16770                 goto alloc_reg;
16771             case 'b':
16772                 reg = 3;
16773                 goto alloc_reg;
16774             case 'c':
16775                 reg = TREG_ECX;
16776                 goto alloc_reg;
16777             case 'd':
16778                 reg = TREG_EDX;
16779                 goto alloc_reg;
16780             case 'S':
16781                 reg = 6;
16782                 goto alloc_reg;
16783             case 'D':
16784                 reg = 7;
16785             alloc_reg:
16786                 if (is_reg_allocated(reg))
16787                     goto try_next;
16788                 goto reg_found;
16789             case 'q':
16790                 /* eax, ebx, ecx or edx */
16791                 for(reg = 0; reg < 4; reg++) {
16792                     if (!is_reg_allocated(reg))
16793                         goto reg_found;
16794                 }
16795                 goto try_next;
16796             case 'r':
16797                 /* any general register */
16798                 for(reg = 0; reg < 8; reg++) {
16799                     if (!is_reg_allocated(reg))
16800                         goto reg_found;
16801                 }
16802                 goto try_next;
16803             reg_found:
16804                 /* now we can reload in the register */
16805                 op->is_llong = 0;
16806                 op->reg = reg;
16807                 regs_allocated[reg] |= reg_mask;
16808                 break;
16809             case 'i':
16810                 if (!((op->vt->r & (VT_VALMASK | VT_LVAL)) == VT_CONST))
16811                     goto try_next;
16812                 break;
16813             case 'I':
16814             case 'N':
16815             case 'M':
16816                 if (!((op->vt->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST))
16817                     goto try_next;
16818                 break;
16819             case 'm':
16820             case 'g':
16821                 /* nothing special to do because the operand is already in
16822                    memory, except if the pointer itself is stored in a
16823                    memory variable (VT_LLOCAL case) */
16824                 /* XXX: fix constant case */
16825                 /* if it is a reference to a memory zone, it must lie
16826                    in a register, so we reserve the register in the
16827                    input registers and a load will be generated
16828                    later */
16829                 if (j < nb_outputs || c == 'm') {
16830                     if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) {
16831                         /* any general register */
16832                         for(reg = 0; reg < 8; reg++) {
16833                             if (!(regs_allocated[reg] & REG_IN_MASK))
16834                                 goto reg_found1;
16835                         }
16836                         goto try_next;
16837                     reg_found1:
16838                         /* now we can reload in the register */
16839                         regs_allocated[reg] |= REG_IN_MASK;
16840                         op->reg = reg;
16841                         op->is_memory = 1;
16842                     }
16843                 }
16844                 break;
16845             default:
16846                 error("asm constraint %d ('%s') could not be satisfied", 
16847                       j, op->constraint);
16848                 break;
16849             }
16850             /* if a reference is present for that operand, we assign it too */
16851             if (op->input_index >= 0) {
16852                 operands[op->input_index].reg = op->reg;
16853                 operands[op->input_index].is_llong = op->is_llong;
16854             }
16855         }
16856         
16857         /* compute out_reg. It is used to store outputs registers to memory
16858            locations references by pointers (VT_LLOCAL case) */
16859         *pout_reg = -1;
16860         for(i=0;i<nb_operands;i++) {
16861             op = &operands[i];
16862             if (op->reg >= 0 && 
16863                 (op->vt->r & VT_VALMASK) == VT_LLOCAL  &&
16864                 !op->is_memory) {
16865                 for(reg = 0; reg < 8; reg++) {
16866                     if (!(regs_allocated[reg] & REG_OUT_MASK))
16867                         goto reg_found2;
16868                 }
16869                 error("could not find free output register for reloading");
16870             reg_found2:
16871                 *pout_reg = reg;
16872                 break;
16873             }
16874         }
16875         
16876         /* print sorted constraints */
16877     #ifdef ASM_DEBUG
16878         for(i=0;i<nb_operands;i++) {
16879             j = sorted_op[i];
16880             op = &operands[j];
16881             printf("%%%d [%s]: \"%s\" r=0x%04x reg=%d\n", 
16882                    j,                
16883                    op->id ? get_tok_str(op->id, NULL) : "", 
16884                    op->constraint,
16885                    op->vt->r,
16886                    op->reg);
16887         }
16888         if (*pout_reg >= 0)
16889             printf("out_reg=%d\n", *pout_reg);
16890     #endif
16891     }
16892     
16893     static void subst_asm_operand(CString *add_str, 
16894                                   SValue *sv, int modifier)
16895     {
16896         int r, reg, size, val;
16897         char buf[64];
16898     
16899         r = sv->r;
16900         if ((r & VT_VALMASK) == VT_CONST) {
16901             if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n')
16902                 cstr_ccat(add_str, '$');
16903             if (r & VT_SYM) {
16904                 cstr_cat(add_str, get_tok_str(sv->sym->v, NULL));
16905                 if (sv->c.i != 0) {
16906                     cstr_ccat(add_str, '+');
16907                 } else {
16908                     return;
16909                 }
16910             }
16911             val = sv->c.i;
16912             if (modifier == 'n')
16913                 val = -val;
16914             snprintf(buf, sizeof(buf), "%d", sv->c.i);
16915             cstr_cat(add_str, buf);
16916         } else if ((r & VT_VALMASK) == VT_LOCAL) {
16917             snprintf(buf, sizeof(buf), "%d(%%ebp)", sv->c.i);
16918             cstr_cat(add_str, buf);
16919         } else if (r & VT_LVAL) {
16920             reg = r & VT_VALMASK;
16921             if (reg >= VT_CONST)
16922                 error("internal compiler error");
16923             snprintf(buf, sizeof(buf), "(%%%s)", 
16924                      get_tok_str(TOK_ASM_eax + reg, NULL));
16925             cstr_cat(add_str, buf);
16926         } else {
16927             /* register case */
16928             reg = r & VT_VALMASK;
16929             if (reg >= VT_CONST)
16930                 error("internal compiler error");
16931     
16932             /* choose register operand size */
16933             if ((sv->type.t & VT_BTYPE) == VT_BYTE)
16934                 size = 1;
16935             else if ((sv->type.t & VT_BTYPE) == VT_SHORT)
16936                 size = 2;
16937             else
16938                 size = 4;
16939             if (size == 1 && reg >= 4)
16940                 size = 4;
16941     
16942             if (modifier == 'b') {
16943                 if (reg >= 4)
16944                     error("cannot use byte register");
16945                 size = 1;
16946             } else if (modifier == 'h') {
16947                 if (reg >= 4)
16948                     error("cannot use byte register");
16949                 size = -1;
16950             } else if (modifier == 'w') {
16951                 size = 2;
16952             }
16953     
16954             switch(size) {
16955             case -1:
16956                 reg = TOK_ASM_ah + reg;
16957                 break;
16958             case 1:
16959                 reg = TOK_ASM_al + reg;
16960                 break;
16961             case 2:
16962                 reg = TOK_ASM_ax + reg;
16963                 break;
16964             default:
16965                 reg = TOK_ASM_eax + reg;
16966                 break;
16967             }
16968             snprintf(buf, sizeof(buf), "%%%s", get_tok_str(reg, NULL));
16969             cstr_cat(add_str, buf);
16970         }
16971     }
16972     
16973     /* generate prolog and epilog code for asm statment */
16974     static void asm_gen_code(ASMOperand *operands, int nb_operands, 
16975                              int nb_outputs, int is_output,
16976                              uint8_t *clobber_regs,
16977                              int out_reg)
16978     {
16979         uint8_t regs_allocated[NB_ASM_REGS];
16980         ASMOperand *op;
16981         int i, reg;
16982         static uint8_t reg_saved[NB_SAVED_REGS] = { 3, 6, 7 };
16983     
16984         /* mark all used registers */
16985         memcpy(regs_allocated, clobber_regs, sizeof(regs_allocated));
16986         for(i = 0; i < nb_operands;i++) {
16987             op = &operands[i];
16988             if (op->reg >= 0)
16989                 regs_allocated[op->reg] = 1;
16990         }
16991         if (!is_output) {
16992             /* generate reg save code */
16993             for(i = 0; i < NB_SAVED_REGS; i++) {
16994                 reg = reg_saved[i];
16995                 if (regs_allocated[reg]) 
16996                     g(0x50 + reg);
16997             }
16998     
16999             /* generate load code */
17000             for(i = 0; i < nb_operands; i++) {
17001                 op = &operands[i];
17002                 if (op->reg >= 0) {
17003                     if ((op->vt->r & VT_VALMASK) == VT_LLOCAL &&
17004                         op->is_memory) {
17005                         /* memory reference case (for both input and
17006                            output cases) */
17007                         SValue sv;
17008                         sv = *op->vt;
17009                         sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
17010                         load(op->reg, &sv);
17011                     } else if (i >= nb_outputs || op->is_rw) {
17012                         /* load value in register */
17013                         load(op->reg, op->vt);
17014                         if (op->is_llong) {
17015                             SValue sv;
17016                             sv = *op->vt;
17017                             sv.c.ul += 4;
17018                             load(TREG_EDX, &sv);
17019                         }
17020                     }
17021                 }
17022             }
17023         } else {
17024             /* generate save code */
17025             for(i = 0 ; i < nb_outputs; i++) {
17026                 op = &operands[i];
17027                 if (op->reg >= 0) {
17028                     if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) {
17029                         if (!op->is_memory) {
17030                             SValue sv;
17031                             sv = *op->vt;
17032                             sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
17033                             load(out_reg, &sv);
17034     
17035                             sv.r = (sv.r & ~VT_VALMASK) | out_reg;
17036                             store(op->reg, &sv);
17037                         }
17038                     } else {
17039                         store(op->reg, op->vt);
17040                         if (op->is_llong) {
17041                             SValue sv;
17042                             sv = *op->vt;
17043                             sv.c.ul += 4;
17044                             store(TREG_EDX, &sv);
17045                         }
17046                     }
17047                 }
17048             }
17049             /* generate reg restore code */
17050             for(i = NB_SAVED_REGS - 1; i >= 0; i--) {
17051                 reg = reg_saved[i];
17052                 if (regs_allocated[reg]) 
17053                     g(0x58 + reg);
17054             }
17055         }
17056     }
17057     
17058     static void asm_clobber(uint8_t *clobber_regs, const char *str)
17059     {
17060         int reg;
17061         TokenSym *ts;
17062     
17063         if (!strcmp(str, "memory") || 
17064             !strcmp(str, "cc"))
17065             return;
17066         ts = tok_alloc(str, strlen(str));
17067         reg = ts->tok;
17068         if (reg >= TOK_ASM_eax && reg <= TOK_ASM_edi) {
17069             reg -= TOK_ASM_eax;
17070         } else if (reg >= TOK_ASM_ax && reg <= TOK_ASM_di) {
17071             reg -= TOK_ASM_ax;
17072         } else {
17073             error("invalid clobber register '%s'", str);
17074         }
17075         clobber_regs[reg] = 1;
17076     }
17077     //---------------------------------------------------------------------------
17078     #endif
17079     // njn: inlined tccasm.c
17080     //#include "tccasm.c"
17081     //---------------------------------------------------------------------------
17082     /*
17083      *  GAS like assembler for TCC
17084      * 
17085      *  Copyright (c) 2001-2004 Fabrice Bellard
17086      *
17087      * This library is free software; you can redistribute it and/or
17088      * modify it under the terms of the GNU Lesser General Public
17089      * License as published by the Free Software Foundation; either
17090      * version 2 of the License, or (at your option) any later version.
17091      *
17092      * This library is distributed in the hope that it will be useful,
17093      * but WITHOUT ANY WARRANTY; without even the implied warranty of
17094      * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17095      * Lesser General Public License for more details.
17096      *
17097      * You should have received a copy of the GNU Lesser General Public
17098      * License along with this library; if not, write to the Free Software
17099      * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17100      */
17101     
17102     static int asm_get_local_label_name(TCCState *s1, unsigned int n)
17103     {
17104         char buf[64];
17105         TokenSym *ts;
17106     
17107         snprintf(buf, sizeof(buf), "L..%u", n);
17108         ts = tok_alloc(buf, strlen(buf));
17109         return ts->tok;
17110     }
17111     
17112     static void asm_expr(TCCState *s1, ExprValue *pe);
17113     
17114     /* We do not use the C expression parser to handle symbols. Maybe the
17115        C expression parser could be tweaked to do so. */
17116     
17117     static void asm_expr_unary(TCCState *s1, ExprValue *pe)
17118     {
17119         Sym *sym;
17120         int op, n, label;
17121         const char *p;
17122     
17123         switch(tok) {
17124         case TOK_PPNUM:
17125             p = tokc.cstr->data;
17126             n = strtoul(p, (char **)&p, 0);
17127             if (*p == 'b' || *p == 'f') {
17128                 /* backward or forward label */
17129                 label = asm_get_local_label_name(s1, n);
17130                 sym = label_find(label);
17131                 if (*p == 'b') {
17132                     /* backward : find the last corresponding defined label */
17133                     if (sym && sym->r == 0)
17134                         sym = sym->prev_tok;
17135                     if (!sym)
17136                         error("local label '%d' not found backward", n);
17137                 } else {
17138                     /* forward */
17139                     if (!sym || sym->r) {
17140                         /* if the last label is defined, then define a new one */
17141                         sym = label_push(&s1->asm_labels, label, 0);
17142                         sym->type.t = VT_STATIC | VT_VOID;
17143                     }
17144                 }
17145                 pe->v = 0;
17146                 pe->sym = sym;
17147             } else if (*p == '\0') {
17148                 pe->v = n;
17149                 pe->sym = NULL;
17150             } else {
17151                 error("invalid number syntax");
17152             }
17153             next();
17154             break;
17155         case '+':
17156             next();
17157             asm_expr_unary(s1, pe);
17158             break;
17159         case '-':
17160         case '~':
17161             op = tok;
17162             next();
17163             asm_expr_unary(s1, pe);
17164             if (pe->sym)
17165                 error("invalid operation with label");
17166             if (op == '-')
17167                 pe->v = -pe->v;
17168             else
17169                 pe->v = ~pe->v;
17170             break;
17171         case TOK_CCHAR:
17172         case TOK_LCHAR:
17173     	pe->v = tokc.i;
17174     	pe->sym = NULL;
17175     	next();
17176     	break;
17177         case '(':
17178             next();
17179             asm_expr(s1, pe);
17180             skip(')');
17181             break;
17182         default:
17183             if (tok >= TOK_IDENT) {
17184                 /* label case : if the label was not found, add one */
17185                 sym = label_find(tok);
17186                 if (!sym) {
17187                     sym = label_push(&s1->asm_labels, tok, 0);
17188                     /* NOTE: by default, the symbol is global */
17189                     sym->type.t = VT_VOID;
17190                 }
17191                 if (sym->r == SHN_ABS) {
17192                     /* if absolute symbol, no need to put a symbol value */
17193                     pe->v = (long)sym->next;
17194                     pe->sym = NULL;
17195                 } else {
17196                     pe->v = 0;
17197                     pe->sym = sym;
17198                 }
17199                 next();
17200             } else {
17201                 error("bad expression syntax [%s]", get_tok_str(tok, &tokc));
17202             }
17203             break;
17204         }
17205     }
17206         
17207     static void asm_expr_prod(TCCState *s1, ExprValue *pe)
17208     {
17209         int op;
17210         ExprValue e2;
17211     
17212         asm_expr_unary(s1, pe);
17213         for(;;) {
17214             op = tok;
17215             if (op != '*' && op != '/' && op != '%' && 
17216                 op != TOK_SHL && op != TOK_SAR)
17217                 break;
17218             next();
17219             asm_expr_unary(s1, &e2);
17220             if (pe->sym || e2.sym)
17221                 error("invalid operation with label");
17222             switch(op) {
17223             case '*':
17224                 pe->v *= e2.v;
17225                 break;
17226             case '/':  
17227                 if (e2.v == 0) {
17228                 div_error:
17229                     error("division by zero");
17230                 }
17231                 pe->v /= e2.v;
17232                 break;
17233             case '%':  
17234                 if (e2.v == 0)
17235                     goto div_error;
17236                 pe->v %= e2.v;
17237                 break;
17238             case TOK_SHL:
17239                 pe->v <<= e2.v;
17240                 break;
17241             default:
17242             case TOK_SAR:
17243                 pe->v >>= e2.v;
17244                 break;
17245             }
17246         }
17247     }
17248     
17249     static void asm_expr_logic(TCCState *s1, ExprValue *pe)
17250     {
17251         int op;
17252         ExprValue e2;
17253     
17254         asm_expr_prod(s1, pe);
17255         for(;;) {
17256             op = tok;
17257             if (op != '&' && op != '|' && op != '^')
17258                 break;
17259             next();
17260             asm_expr_prod(s1, &e2);
17261             if (pe->sym || e2.sym)
17262                 error("invalid operation with label");
17263             switch(op) {
17264             case '&':
17265                 pe->v &= e2.v;
17266                 break;
17267             case '|':  
17268                 pe->v |= e2.v;
17269                 break;
17270             default:
17271             case '^':
17272                 pe->v ^= e2.v;
17273                 break;
17274             }
17275         }
17276     }
17277     
17278     static inline void asm_expr_sum(TCCState *s1, ExprValue *pe)
17279     {
17280         int op;
17281         ExprValue e2;
17282     
17283         asm_expr_logic(s1, pe);
17284         for(;;) {
17285             op = tok;
17286             if (op != '+' && op != '-')
17287                 break;
17288             next();
17289             asm_expr_logic(s1, &e2);
17290             if (op == '+') {
17291                 if (pe->sym != NULL && e2.sym != NULL)
17292                     goto cannot_relocate;
17293                 pe->v += e2.v;
17294                 if (pe->sym == NULL && e2.sym != NULL)
17295                     pe->sym = e2.sym;
17296             } else {
17297                 pe->v -= e2.v;
17298                 /* NOTE: we are less powerful than gas in that case
17299                    because we store only one symbol in the expression */
17300                 if (!pe->sym && !e2.sym) {
17301                     /* OK */
17302                 } else if (pe->sym && !e2.sym) {
17303                     /* OK */
17304                 } else if (pe->sym && e2.sym) {
17305                     if (pe->sym == e2.sym) { 
17306                         /* OK */
17307                     } else if (pe->sym->r == e2.sym->r && pe->sym->r != 0) {
17308                         /* we also accept defined symbols in the same section */
17309                         pe->v += (long)pe->sym->next - (long)e2.sym->next;
17310                     } else {
17311                         goto cannot_relocate;
17312                     }
17313                     pe->sym = NULL; /* same symbols can be substracted to NULL */
17314                 } else {
17315                 cannot_relocate:
17316                     error("invalid operation with label");
17317                 }
17318             }
17319         }
17320     }
17321     
17322     static void asm_expr(TCCState *s1, ExprValue *pe)
17323     {
17324         asm_expr_sum(s1, pe);
17325     }
17326     
17327     static int asm_int_expr(TCCState *s1)
17328     {
17329         ExprValue e;
17330         asm_expr(s1, &e);
17331         if (e.sym)
17332             expect("constant");
17333         return e.v;
17334     }
17335     
17336     /* NOTE: the same name space as C labels is used to avoid using too
17337        much memory when storing labels in TokenStrings */
17338     static void asm_new_label1(TCCState *s1, int label, int is_local,
17339                                int sh_num, long value)
17340     {
17341         Sym *sym;
17342     
17343         sym = label_find(label);
17344         if (sym) {
17345             if (sym->r) {
17346                 /* the label is already defined */
17347                 if (!is_local) {
17348                     error("assembler label '%s' already defined", 
17349                           get_tok_str(label, NULL));
17350                 } else {
17351                     /* redefinition of local labels is possible */
17352                     goto new_label;
17353                 }
17354             }
17355         } else {
17356         new_label:
17357             sym = label_push(&s1->asm_labels, label, 0);
17358             sym->type.t = VT_STATIC | VT_VOID;
17359         }
17360         sym->r = sh_num;
17361         sym->next = (void *)value;
17362     }
17363     
17364     static void asm_new_label(TCCState *s1, int label, int is_local)
17365     {
17366         asm_new_label1(s1, label, is_local, cur_text_section->sh_num, ind);
17367     }
17368     
17369     static void asm_free_labels(TCCState *st)
17370     {
17371         Sym *s, *s1;
17372         Section *sec;
17373         
17374         for(s = st->asm_labels; s != NULL; s = s1) {
17375             s1 = s->prev;
17376             /* define symbol value in object file */
17377             if (s->r) {
17378                 if (s->r == SHN_ABS)
17379                     sec = SECTION_ABS;
17380                 else
17381                     sec = st->sections[s->r];
17382                 put_extern_sym2(s, sec, (long)s->next, 0, 0);
17383             }
17384             /* remove label */
17385             table_ident[s->v - TOK_IDENT]->sym_label = NULL;
17386             sym_free(s);
17387         }
17388         st->asm_labels = NULL;
17389     }
17390     
17391     static void use_section1(TCCState *s1, Section *sec)
17392     {
17393         cur_text_section->data_offset = ind;
17394         cur_text_section = sec;
17395         ind = cur_text_section->data_offset;
17396     }
17397     
17398     static void use_section(TCCState *s1, const char *name)
17399     {
17400         Section *sec;
17401         sec = find_section(s1, name);
17402         use_section1(s1, sec);
17403     }
17404     
17405     static void asm_parse_directive(TCCState *s1)
17406     {
17407         int n, offset, v, size, tok1;
17408         Section *sec;
17409         uint8_t *ptr;
17410     
17411         /* assembler directive */
17412         next();
17413         sec = cur_text_section;
17414         switch(tok) {
17415         case TOK_ASM_align:
17416         case TOK_ASM_skip:
17417         case TOK_ASM_space:
17418             tok1 = tok;
17419             next();
17420             n = asm_int_expr(s1);
17421             if (tok1 == TOK_ASM_align) {
17422                 if (n < 0 || (n & (n-1)) != 0)
17423                     error("alignment must be a positive power of two");
17424                 offset = (ind + n - 1) & -n;
17425                 size = offset - ind;
17426                 /* the section must have a compatible alignment */
17427                 if (sec->sh_addralign < n)
17428                     sec->sh_addralign = n;
17429             } else {
17430                 size = n;
17431             }
17432             v = 0;
17433             if (tok == ',') {
17434                 next();
17435                 v = asm_int_expr(s1);
17436             }
17437         zero_pad:
17438             if (sec->sh_type != SHT_NOBITS) {
17439                 sec->data_offset = ind;
17440                 ptr = section_ptr_add(sec, size);
17441                 memset(ptr, v, size);
17442             }
17443             ind += size;
17444             break;
17445         case TOK_ASM_quad:
17446             next();
17447             for(;;) {
17448                 uint64_t vl;
17449                 const char *p;
17450     
17451                 p = tokc.cstr->data;
17452                 if (tok != TOK_PPNUM) {
17453                 error_constant:
17454                     error("64 bit constant");
17455                 }
17456                 vl = strtoll(p, (char **)&p, 0);
17457                 if (*p != '\0')
17458                     goto error_constant;
17459                 next();
17460                 if (sec->sh_type != SHT_NOBITS) {
17461                     /* XXX: endianness */
17462                     gen_le32(vl);
17463                     gen_le32(vl >> 32);
17464                 } else {
17465                     ind += 8;
17466                 }
17467                 if (tok != ',')
17468                     break;
17469                 next();
17470             }
17471             break;
17472         case TOK_ASM_byte:
17473             size = 1;
17474             goto asm_data;
17475         case TOK_ASM_word:
17476         case TOK_SHORT:
17477             size = 2;
17478             goto asm_data;
17479         case TOK_LONG:
17480         case TOK_INT:
17481             size = 4;
17482         asm_data:
17483             next();
17484             for(;;) {
17485                 ExprValue e;
17486                 asm_expr(s1, &e);
17487                 if (sec->sh_type != SHT_NOBITS) {
17488                     if (size == 4) {
17489                         gen_expr32(&e);
17490                     } else {
17491                         if (e.sym)
17492                             expect("constant");
17493                         if (size == 1)
17494                             g(e.v);
17495                         else
17496                             gen_le16(e.v);
17497                     }
17498                 } else {
17499                     ind += size;
17500                 }
17501                 if (tok != ',')
17502                     break;
17503                 next();
17504             }
17505             break;
17506         case TOK_ASM_fill:
17507             {
17508                 int repeat, size, val, i, j;
17509                 uint8_t repeat_buf[8];
17510                 next();
17511                 repeat = asm_int_expr(s1);
17512                 if (repeat < 0) {
17513                     error("repeat < 0; .fill ignored");
17514                     break;
17515                 }
17516                 size = 1;
17517                 val = 0;
17518                 if (tok == ',') {
17519                     next();
17520                     size = asm_int_expr(s1);
17521                     if (size < 0) {
17522                         error("size < 0; .fill ignored");
17523                         break;
17524                     }
17525                     if (size > 8)
17526                         size = 8;
17527                     if (tok == ',') {
17528                         next();
17529                         val = asm_int_expr(s1);
17530                     }
17531                 }
17532                 /* XXX: endianness */
17533                 repeat_buf[0] = val;
17534                 repeat_buf[1] = val >> 8;
17535                 repeat_buf[2] = val >> 16;
17536                 repeat_buf[3] = val >> 24;
17537                 repeat_buf[4] = 0;
17538                 repeat_buf[5] = 0;
17539                 repeat_buf[6] = 0;
17540                 repeat_buf[7] = 0;
17541                 for(i = 0; i < repeat; i++) {
17542                     for(j = 0; j < size; j++) {
17543                         g(repeat_buf[j]);
17544                     }
17545                 }
17546             }
17547             break;
17548         case TOK_ASM_org:
17549             {
17550                 unsigned long n;
17551                 next();
17552                 /* XXX: handle section symbols too */
17553                 n = asm_int_expr(s1);
17554                 if (n < ind)
17555                     error("attempt to .org backwards");
17556                 v = 0;
17557                 size = n - ind;
17558                 goto zero_pad;
17559             }
17560             break;
17561         case TOK_ASM_globl:
17562         case TOK_ASM_global:
17563     	{ 
17564                 Sym *sym;
17565     
17566                 next();
17567                 sym = label_find(tok);
17568                 if (!sym) {
17569                     sym = label_push(&s1->asm_labels, tok, 0);
17570                     sym->type.t = VT_VOID;
17571                 }
17572                 sym->type.t &= ~VT_STATIC;
17573                 next();
17574     	}
17575     	break;
17576         case TOK_ASM_string:
17577         case TOK_ASM_ascii:
17578         case TOK_ASM_asciz:
17579             {
17580                 const uint8_t *p;
17581                 int i, size, t;
17582     
17583                 t = tok;
17584                 next();
17585                 for(;;) {
17586                     if (tok != TOK_STR)
17587                         expect("string constant");
17588                     p = tokc.cstr->data;
17589                     size = tokc.cstr->size;
17590                     if (t == TOK_ASM_ascii && size > 0)
17591                         size--;
17592                     for(i = 0; i < size; i++)
17593                         g(p[i]);
17594                     next();
17595                     if (tok == ',') {
17596                         next();
17597                     } else if (tok != TOK_STR) {
17598                         break;
17599                     }
17600                 }
17601     	}
17602     	break;
17603         case TOK_ASM_text:
17604         case TOK_ASM_data:
17605         case TOK_ASM_bss:
17606     	{ 
17607                 char sname[64];
17608                 tok1 = tok;
17609                 n = 0;
17610                 next();
17611                 if (tok != ';' && tok != TOK_LINEFEED) {
17612     		n = asm_int_expr(s1);
17613     		next();
17614                 }
17615                 sprintf(sname, (n?".%s%d":".%s"), get_tok_str(tok1, NULL), n);
17616                 use_section(s1, sname);
17617     	}
17618     	break;
17619         case TOK_SECTION1:
17620             {
17621                 char sname[256];
17622     
17623                 /* XXX: support more options */
17624                 next();
17625                 sname[0] = '\0';
17626                 while (tok != ';' && tok != TOK_LINEFEED && tok != ',') {
17627                     if (tok == TOK_STR)
17628                         pstrcat(sname, sizeof(sname), tokc.cstr->data);
17629                     else
17630                         pstrcat(sname, sizeof(sname), get_tok_str(tok, NULL));
17631                     next();
17632                 }
17633                 if (tok == ',') {
17634                     /* skip section options */
17635                     next();
17636                     if (tok != TOK_STR)
17637                         expect("string constant");
17638                     next();
17639                 }
17640                 last_text_section = cur_text_section;
17641                 use_section(s1, sname);
17642             }
17643             break;
17644         case TOK_ASM_previous:
17645             { 
17646                 Section *sec;
17647                 next();
17648                 if (!last_text_section)
17649                     error("no previous section referenced");
17650                 sec = cur_text_section;
17651                 use_section1(s1, last_text_section);
17652                 last_text_section = sec;
17653             }
17654             break;
17655         default:
17656             error("unknown assembler directive '.%s'", get_tok_str(tok, NULL));
17657             break;
17658         }
17659     }
17660     
17661     
17662     /* assemble a file */
17663     static int tcc_assemble_internal(TCCState *s1, int do_preprocess)
17664     {
17665         int opcode;
17666     
17667     #if 0
17668         /* print stats about opcodes */
17669         {
17670             const ASMInstr *pa;
17671             int freq[4];
17672             int op_vals[500];
17673             int nb_op_vals, i, j;
17674     
17675             nb_op_vals = 0;
17676             memset(freq, 0, sizeof(freq));
17677             for(pa = asm_instrs; pa->sym != 0; pa++) {
17678                 freq[pa->nb_ops]++;
17679                 for(i=0;i<pa->nb_ops;i++) {
17680                     for(j=0;j<nb_op_vals;j++) {
17681                         if (pa->op_type[i] == op_vals[j])
17682                             goto found;
17683                     }
17684                     op_vals[nb_op_vals++] = pa->op_type[i];
17685                 found: ;
17686                 }
17687             }
17688             for(i=0;i<nb_op_vals;i++) {
17689                 int v = op_vals[i];
17690                 if ((v & (v - 1)) != 0)
17691                     printf("%3d: %08x\n", i, v);
17692             }
17693             printf("size=%d nb=%d f0=%d f1=%d f2=%d f3=%d\n",
17694                    sizeof(asm_instrs), sizeof(asm_instrs) / sizeof(ASMInstr),
17695                    freq[0], freq[1], freq[2], freq[3]);
17696         }
17697     #endif
17698     
17699         /* XXX: undefine C labels */
17700     
17701         ch = file->buf_ptr[0];
17702         tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
17703         parse_flags = PARSE_FLAG_ASM_COMMENTS;
17704         if (do_preprocess)
17705             parse_flags |= PARSE_FLAG_PREPROCESS;
17706         next();
17707         for(;;) {
17708             if (tok == TOK_EOF)
17709                 break;
17710             parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
17711         redo:
17712             if (tok == '#') {
17713                 /* horrible gas comment */
17714                 while (tok != TOK_LINEFEED)
17715                     next();
17716             } else if (tok == '.') {
17717                 asm_parse_directive(s1);
17718             } else if (tok == TOK_PPNUM) {
17719                 const char *p;
17720                 int n;
17721                 p = tokc.cstr->data;
17722                 n = strtoul(p, (char **)&p, 10);
17723                 if (*p != '\0')
17724                     expect("':'");
17725                 /* new local label */
17726                 asm_new_label(s1, asm_get_local_label_name(s1, n), 1);
17727                 next();
17728                 skip(':');
17729                 goto redo;
17730             } else if (tok >= TOK_IDENT) {
17731                 /* instruction or label */
17732                 opcode = tok;
17733                 next();
17734                 if (tok == ':') {
17735                     /* new label */
17736                     asm_new_label(s1, opcode, 0);
17737                     next();
17738                     goto redo;
17739                 } else if (tok == '=') {
17740                     int n;
17741                     next();
17742                     n = asm_int_expr(s1);
17743                     asm_new_label1(s1, opcode, 0, SHN_ABS, n);
17744                     goto redo;
17745                 } else {
17746                     asm_opcode(s1, opcode);
17747                 }
17748             }
17749             /* end of line */
17750             if (tok != ';' && tok != TOK_LINEFEED){
17751                 expect("end of line");
17752             }
17753             parse_flags &= ~PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
17754             next();
17755         }
17756     
17757         asm_free_labels(s1);
17758     
17759         return 0;
17760     }
17761     
17762     /* Assemble the current file */
17763     static int tcc_assemble(TCCState *s1, int do_preprocess)
17764     {
17765         Sym *define_start;
17766         int ret;
17767     
17768         preprocess_init(s1);
17769     
17770         /* default section is text */
17771         cur_text_section = text_section;
17772         ind = cur_text_section->data_offset;
17773     
17774         define_start = define_stack;
17775     
17776         ret = tcc_assemble_internal(s1, do_preprocess);
17777     
17778         cur_text_section->data_offset = ind;
17779     
17780         free_defines(define_start); 
17781     
17782         return ret;
17783     }
17784     
17785     /********************************************************************/
17786     /* GCC inline asm support */
17787     
17788     /* assemble the string 'str' in the current C compilation unit without
17789        C preprocessing. NOTE: str is modified by modifying the '\0' at the
17790        end */
17791     static void tcc_assemble_inline(TCCState *s1, char *str, int len)
17792     {
17793         BufferedFile *bf, *saved_file;
17794         int saved_parse_flags, *saved_macro_ptr;
17795     
17796         bf = tcc_malloc(sizeof(BufferedFile));
17797         memset(bf, 0, sizeof(BufferedFile));
17798         bf->fd = -1;
17799         bf->buf_ptr = str;
17800         bf->buf_end = str + len;
17801         str[len] = CH_EOB;
17802         /* same name as current file so that errors are correctly
17803            reported */
17804         pstrcpy(bf->filename, sizeof(bf->filename), file->filename);
17805         bf->line_num = file->line_num;
17806         saved_file = file;
17807         file = bf;
17808         saved_parse_flags = parse_flags;
17809         saved_macro_ptr = macro_ptr;
17810         macro_ptr = NULL;
17811         
17812         tcc_assemble_internal(s1, 0);
17813     
17814         parse_flags = saved_parse_flags;
17815         macro_ptr = saved_macro_ptr;
17816         file = saved_file;
17817         tcc_free(bf);
17818     }
17819     
17820     /* find a constraint by its number or id (gcc 3 extended
17821        syntax). return -1 if not found. Return in *pp in char after the
17822        constraint */
17823     static int find_constraint(ASMOperand *operands, int nb_operands, 
17824                                const char *name, const char **pp)
17825     {
17826         int index;
17827         TokenSym *ts;
17828         const char *p;
17829     
17830         if (isnum(*name)) {
17831             index = 0;
17832             while (isnum(*name)) {
17833                 index = (index * 10) + (*name) - '0';
17834                 name++;
17835             }
17836             if ((unsigned)index >= nb_operands)
17837                 index = -1;
17838         } else if (*name == '[') {
17839             name++;
17840             p = strchr(name, ']');
17841             if (p) {
17842                 ts = tok_alloc(name, p - name);
17843                 for(index = 0; index < nb_operands; index++) {
17844                     if (operands[index].id == ts->tok)
17845                         goto found;
17846                 }
17847                 index = -1;
17848             found:
17849                 name = p + 1;
17850             } else {
17851                 index = -1;
17852             }
17853         } else {
17854             index = -1;
17855         }
17856         if (pp)
17857             *pp = name;
17858         return index;
17859     }
17860     
17861     static void subst_asm_operands(ASMOperand *operands, int nb_operands, 
17862                                    int nb_outputs,
17863                                    CString *out_str, CString *in_str)
17864     {
17865         int c, index, modifier;
17866         const char *str;
17867         ASMOperand *op;
17868         SValue sv;
17869     
17870         cstr_new(out_str);
17871         str = in_str->data;
17872         for(;;) {
17873             c = *str++;
17874             if (c == '%') {
17875                 if (*str == '%') {
17876                     str++;
17877                     goto add_char;
17878                 }
17879                 modifier = 0;
17880                 if (*str == 'c' || *str == 'n' ||
17881                     *str == 'b' || *str == 'w' || *str == 'h')
17882                     modifier = *str++;
17883                 index = find_constraint(operands, nb_operands, str, &str);
17884                 if (index < 0)
17885                     error("invalid operand reference after %%");
17886                 op = &operands[index];
17887                 sv = *op->vt;
17888                 if (op->reg >= 0) {
17889                     sv.r = op->reg;
17890                     if ((op->vt->r & VT_VALMASK) == VT_LLOCAL)
17891                         sv.r |= VT_LVAL;
17892                 }
17893                 subst_asm_operand(out_str, &sv, modifier);
17894             } else {
17895             add_char:
17896                 cstr_ccat(out_str, c);
17897                 if (c == '\0')
17898                     break;
17899             }
17900         }
17901     }
17902     
17903     
17904     static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr,
17905                                    int is_output)
17906     {
17907         ASMOperand *op;
17908         int nb_operands;
17909     
17910         if (tok != ':') {
17911             nb_operands = *nb_operands_ptr;
17912             for(;;) {
17913                 if (nb_operands >= MAX_ASM_OPERANDS)
17914                     error("too many asm operands");
17915                 op = &operands[nb_operands++];
17916                 op->id = 0;
17917                 if (tok == '[') {
17918                     next();
17919                     if (tok < TOK_IDENT)
17920                         expect("identifier");
17921                     op->id = tok;
17922                     next();
17923                     skip(']');
17924                 }
17925                 if (tok != TOK_STR)
17926                     expect("string constant");
17927                 op->constraint = tcc_malloc(tokc.cstr->size);
17928                 strcpy(op->constraint, tokc.cstr->data);
17929                 next();
17930                 skip('(');
17931                 gexpr();
17932                 if (is_output) {
17933                     test_lvalue();
17934                 } else {
17935                     /* we want to avoid LLOCAL case, except when the 'm'
17936                        constraint is used. Note that it may come from
17937                        register storage, so we need to convert (reg)
17938                        case */
17939                     if ((vtop->r & VT_LVAL) &&
17940                         ((vtop->r & VT_VALMASK) == VT_LLOCAL ||
17941                          (vtop->r & VT_VALMASK) < VT_CONST) &&
17942                         !strchr(op->constraint, 'm')) {
17943                         gv(RC_INT);
17944                     }
17945                 }
17946                 op->vt = vtop;
17947                 skip(')');
17948                 if (tok == ',') {
17949                     next();
17950                 } else {
17951                     break;
17952                 }
17953             }
17954             *nb_operands_ptr = nb_operands;
17955         }
17956     }
17957     
17958     static void parse_asm_str(CString *astr)
17959     {
17960         skip('(');
17961         /* read the string */
17962         if (tok != TOK_STR)
17963             expect("string constant");
17964         cstr_new(astr);
17965         while (tok == TOK_STR) {
17966             /* XXX: add \0 handling too ? */
17967             cstr_cat(astr, tokc.cstr->data);
17968             next();
17969         }
17970         cstr_ccat(astr, '\0');
17971     }
17972     
17973     /* parse the GCC asm() instruction */
17974     static void asm_instr(void)
17975     {
17976         CString astr, astr1;
17977         ASMOperand operands[MAX_ASM_OPERANDS];
17978         int nb_inputs __attribute__((unused));
17979         int nb_outputs, nb_operands, i, must_subst, out_reg;
17980         uint8_t clobber_regs[NB_ASM_REGS];
17981     
17982         next();
17983         /* since we always generate the asm() instruction, we can ignore
17984            volatile */
17985         if (tok == TOK_VOLATILE1 || tok == TOK_VOLATILE2 || tok == TOK_VOLATILE3) {
17986             next();
17987         }
17988         parse_asm_str(&astr);
17989         nb_operands = 0;
17990         nb_outputs = 0;
17991         must_subst = 0;
17992         memset(clobber_regs, 0, sizeof(clobber_regs));
17993         if (tok == ':') {
17994             next();
17995             must_subst = 1;
17996             /* output args */
17997             parse_asm_operands(operands, &nb_operands, 1);
17998             nb_outputs = nb_operands;
17999             if (tok == ':') {
18000                 next();
18001                 /* input args */
18002                 parse_asm_operands(operands, &nb_operands, 0);
18003                 if (tok == ':') {
18004                     /* clobber list */
18005                     /* XXX: handle registers */
18006                     next();
18007                     for(;;) {
18008                         if (tok != TOK_STR)
18009                             expect("string constant");
18010                         asm_clobber(clobber_regs, tokc.cstr->data);
18011                         next();
18012                         if (tok == ',') {
18013                             next();
18014                         } else {
18015                             break;
18016                         }
18017                     }
18018                 }
18019             }
18020         }
18021         skip(')');
18022         /* NOTE: we do not eat the ';' so that we can restore the current
18023            token after the assembler parsing */
18024         if (tok != ';')
18025             expect("';'");
18026         nb_inputs = nb_operands - nb_outputs;
18027         
18028         /* save all values in the memory */
18029         save_regs(0);
18030     
18031         /* compute constraints */
18032         asm_compute_constraints(operands, nb_operands, nb_outputs, 
18033                                 clobber_regs, &out_reg);
18034     
18035         /* substitute the operands in the asm string. No substitution is
18036            done if no operands (GCC behaviour) */
18037     #ifdef ASM_DEBUG
18038         printf("asm: \"%s\"\n", (char *)astr.data);
18039     #endif
18040         if (must_subst) {
18041             subst_asm_operands(operands, nb_operands, nb_outputs, &astr1, &astr);
18042             cstr_free(&astr);
18043         } else {
18044             astr1 = astr;
18045         }
18046     #ifdef ASM_DEBUG
18047         printf("subst_asm: \"%s\"\n", (char *)astr1.data);
18048     #endif
18049     
18050         /* generate loads */
18051         asm_gen_code(operands, nb_operands, nb_outputs, 0, 
18052                      clobber_regs, out_reg);    
18053     
18054         /* assemble the string with tcc internal assembler */
18055         tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1);
18056     
18057         /* restore the current C token */
18058         next();
18059     
18060         /* store the output values if needed */
18061         asm_gen_code(operands, nb_operands, nb_outputs, 1, 
18062                      clobber_regs, out_reg);
18063         
18064         /* free everything */
18065         for(i=0;i<nb_operands;i++) {
18066             ASMOperand *op;
18067             op = &operands[i];
18068             tcc_free(op->constraint);
18069             vpop();
18070         }
18071         cstr_free(&astr1);
18072     }
18073     
18074     static void asm_global_instr(void)
18075     {
18076         CString astr;
18077     
18078         next();
18079         parse_asm_str(&astr);
18080         skip(')');
18081         /* NOTE: we do not eat the ';' so that we can restore the current
18082            token after the assembler parsing */
18083         if (tok != ';')
18084             expect("';'");
18085         
18086     #ifdef ASM_DEBUG
18087         printf("asm_global: \"%s\"\n", (char *)astr.data);
18088     #endif
18089         cur_text_section = text_section;
18090         ind = cur_text_section->data_offset;
18091     
18092         /* assemble the string with tcc internal assembler */
18093         tcc_assemble_inline(tcc_state, astr.data, astr.size - 1);
18094         
18095         cur_text_section->data_offset = ind;
18096     
18097         /* restore the current C token */
18098         next();
18099     
18100         cstr_free(&astr);
18101     }
18102     //---------------------------------------------------------------------------
18103     
18104     #else
18105     static void asm_instr(void)
18106     {
18107         error("inline asm() not supported");
18108     }
18109     static void asm_global_instr(void)
18110     {
18111         error("inline asm() not supported");
18112     }
18113     #endif
18114     
18115     // njn: inlined tccelf.c
18116     //#include "tccelf.c"
18117     //---------------------------------------------------------------------------
18118     /*
18119      *  ELF file handling for TCC
18120      * 
18121      *  Copyright (c) 2001-2004 Fabrice Bellard
18122      *
18123      * This library is free software; you can redistribute it and/or
18124      * modify it under the terms of the GNU Lesser General Public
18125      * License as published by the Free Software Foundation; either
18126      * version 2 of the License, or (at your option) any later version.
18127      *
18128      * This library is distributed in the hope that it will be useful,
18129      * but WITHOUT ANY WARRANTY; without even the implied warranty of
18130      * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18131      * Lesser General Public License for more details.
18132      *
18133      * You should have received a copy of the GNU Lesser General Public
18134      * License along with this library; if not, write to the Free Software
18135      * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18136      */
18137     
18138     static int put_elf_str(Section *s, const char *sym)
18139     {
18140         int offset, len;
18141         char *ptr;
18142     
18143         len = strlen(sym) + 1;
18144         offset = s->data_offset;
18145         ptr = section_ptr_add(s, len);
18146         memcpy(ptr, sym, len);
18147         return offset;
18148     }
18149     
18150     /* elf symbol hashing function */
18151     static unsigned long elf_hash(const unsigned char *name)
18152     {
18153         unsigned long h = 0, g;
18154         
18155         while (*name) {
18156             h = (h << 4) + *name++;
18157             g = h & 0xf0000000;
18158             if (g)
18159                 h ^= g >> 24;
18160             h &= ~g;
18161         }
18162         return h;
18163     }
18164     
18165     /* rebuild hash table of section s */
18166     /* NOTE: we do factorize the hash table code to go faster */
18167     static void rebuild_hash(Section *s, unsigned int nb_buckets)
18168     {
18169         Elf32_Sym *sym;
18170         int *ptr, *hash, nb_syms, sym_index, h;
18171         char *strtab;
18172     
18173         strtab = s->link->data;
18174         nb_syms = s->data_offset / sizeof(Elf32_Sym);
18175     
18176         s->hash->data_offset = 0;
18177         ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
18178         ptr[0] = nb_buckets;
18179         ptr[1] = nb_syms;
18180         ptr += 2;
18181         hash = ptr;
18182         memset(hash, 0, (nb_buckets + 1) * sizeof(int));
18183         ptr += nb_buckets + 1;
18184     
18185         sym = (Elf32_Sym *)s->data + 1;
18186         for(sym_index = 1; sym_index < nb_syms; sym_index++) {
18187             if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
18188                 h = elf_hash(strtab + sym->st_name) % nb_buckets;
18189                 *ptr = hash[h];
18190                 hash[h] = sym_index;
18191             } else {
18192                 *ptr = 0;
18193             }
18194             ptr++;
18195             sym++;
18196         }
18197     }
18198     
18199     /* return the symbol number */
18200     static int put_elf_sym(Section *s, 
18201                            unsigned long value, unsigned long size,
18202                            int info, int other, int shndx, const char *name)
18203     {
18204         int name_offset, sym_index;
18205         int nbuckets, h;
18206         Elf32_Sym *sym;
18207         Section *hs;
18208         
18209         sym = section_ptr_add(s, sizeof(Elf32_Sym));
18210         if (name)
18211             name_offset = put_elf_str(s->link, name);
18212         else
18213             name_offset = 0;
18214         /* XXX: endianness */
18215         sym->st_name = name_offset;
18216         sym->st_value = value;
18217         sym->st_size = size;
18218         sym->st_info = info;
18219         sym->st_other = other;
18220         sym->st_shndx = shndx;
18221         sym_index = sym - (Elf32_Sym *)s->data;
18222         hs = s->hash;
18223         if (hs) {
18224             int *ptr, *base;
18225             ptr = section_ptr_add(hs, sizeof(int));
18226             base = (int *)hs->data;
18227             /* only add global or weak symbols */
18228             if (ELF32_ST_BIND(info) != STB_LOCAL) {
18229                 /* add another hashing entry */
18230                 nbuckets = base[0];
18231                 h = elf_hash(name) % nbuckets;
18232                 *ptr = base[2 + h];
18233                 base[2 + h] = sym_index;
18234                 base[1]++;
18235                 /* we resize the hash table */
18236                 hs->nb_hashed_syms++;
18237                 if (hs->nb_hashed_syms > 2 * nbuckets) {
18238                     rebuild_hash(s, 2 * nbuckets);
18239                 }
18240             } else {
18241                 *ptr = 0;
18242                 base[1]++;
18243             }
18244         }
18245         return sym_index;
18246     }
18247     
18248     /* find global ELF symbol 'name' and return its index. Return 0 if not
18249        found. */
18250     static int find_elf_sym(Section *s, const char *name)
18251     {
18252         Elf32_Sym *sym;
18253         Section *hs;
18254         int nbuckets, sym_index, h;
18255         const char *name1;
18256         
18257         hs = s->hash;
18258         if (!hs)
18259             return 0;
18260         nbuckets = ((int *)hs->data)[0];
18261         h = elf_hash(name) % nbuckets;
18262         sym_index = ((int *)hs->data)[2 + h];
18263         while (sym_index != 0) {
18264             sym = &((Elf32_Sym *)s->data)[sym_index];
18265             name1 = s->link->data + sym->st_name;
18266             if (!strcmp(name, name1))
18267                 return sym_index;
18268             sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
18269         }
18270         return 0;
18271     }
18272     
18273     /* return elf symbol value or error */
18274     int tcc_get_symbol(TCCState *s, unsigned long *pval, const char *name)
18275     {
18276         int sym_index;
18277         Elf32_Sym *sym;
18278         
18279         sym_index = find_elf_sym(symtab_section, name);
18280         if (!sym_index)
18281             return -1;
18282         sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
18283         *pval = sym->st_value;
18284         return 0;
18285     }
18286     
18287     void *tcc_get_symbol_err(TCCState *s, const char *name)
18288     {
18289         unsigned long val;
18290         if (tcc_get_symbol(s, &val, name) < 0)
18291             error("%s not defined", name);
18292         return (void *)val;
18293     }
18294     
18295     /* add an elf symbol : check if it is already defined and patch
18296        it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
18297     static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
18298                            int info, int other, int sh_num, const char *name)
18299     {
18300         Elf32_Sym *esym;
18301         int sym_bind, sym_index, sym_type, esym_bind;
18302     
18303         sym_bind = ELF32_ST_BIND(info);
18304         sym_type = ELF32_ST_TYPE(info);
18305             
18306         if (sym_bind != STB_LOCAL) {
18307             /* we search global or weak symbols */
18308             sym_index = find_elf_sym(s, name);
18309             if (!sym_index)
18310                 goto do_def;
18311             esym = &((Elf32_Sym *)s->data)[sym_index];
18312             if (esym->st_shndx != SHN_UNDEF) {
18313                 esym_bind = ELF32_ST_BIND(esym->st_info);
18314                 if (sh_num == SHN_UNDEF) {
18315                     /* ignore adding of undefined symbol if the
18316                        corresponding symbol is already defined */
18317                 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
18318                     /* global overrides weak, so patch */
18319                     goto do_patch;
18320                 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
18321                     /* weak is ignored if already global */
18322                 } else {
18323     #if 0
18324                     printf("new_bind=%d new_shndx=%d last_bind=%d old_shndx=%d\n",
18325                            sym_bind, sh_num, esym_bind, esym->st_shndx);
18326     #endif
18327                     /* NOTE: we accept that two DLL define the same symbol */
18328                     if (s != tcc_state->dynsymtab_section)
18329                         error_noabort("'%s' defined twice", name);
18330                 }
18331             } else {
18332             do_patch:
18333                 esym->st_info = ELF32_ST_INFO(sym_bind, sym_type);
18334                 esym->st_shndx = sh_num;
18335                 esym->st_value = value;
18336                 esym->st_size = size;
18337                 esym->st_other = other;
18338             }
18339         } else {
18340         do_def:
18341             sym_index = put_elf_sym(s, value, size, 
18342                                     ELF32_ST_INFO(sym_bind, sym_type), other, 
18343                                     sh_num, name);
18344         }
18345         return sym_index;
18346     }
18347     
18348     /* put relocation */
18349     static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
18350                               int type, int symbol)
18351     {
18352         char buf[256];
18353         Section *sr;
18354         Elf32_Rel *rel;
18355     
18356         sr = s->reloc;
18357         if (!sr) {
18358             /* if no relocation section, create it */
18359             snprintf(buf, sizeof(buf), ".rel%s", s->name);
18360             /* if the symtab is allocated, then we consider the relocation
18361                are also */
18362             sr = new_section(tcc_state, buf, SHT_REL, symtab->sh_flags);
18363             sr->sh_entsize = sizeof(Elf32_Rel);
18364             sr->link = symtab;
18365             sr->sh_info = s->sh_num;
18366             s->reloc = sr;
18367         }
18368         rel = section_ptr_add(sr, sizeof(Elf32_Rel));
18369         rel->r_offset = offset;
18370         rel->r_info = ELF32_R_INFO(symbol, type);
18371     }
18372     
18373     /* put stab debug information */
18374     
18375     typedef struct {
18376         unsigned long n_strx;         /* index into string table of name */
18377         unsigned char n_type;         /* type of symbol */
18378         unsigned char n_other;        /* misc info (usually empty) */
18379         unsigned short n_desc;        /* description field */
18380         unsigned long n_value;        /* value of symbol */
18381     } Stab_Sym;
18382     
18383     static void put_stabs(const char *str, int type, int other, int desc, 
18384                           unsigned long value)
18385     {
18386         Stab_Sym *sym;
18387     
18388         sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
18389         if (str) {
18390             sym->n_strx = put_elf_str(stabstr_section, str);
18391         } else {
18392             sym->n_strx = 0;
18393         }
18394         sym->n_type = type;
18395         sym->n_other = other;
18396         sym->n_desc = desc;
18397         sym->n_value = value;
18398     }
18399     
18400     static void put_stabs_r(const char *str, int type, int other, int desc, 
18401                             unsigned long value, Section *sec, int sym_index)
18402     {
18403         put_stabs(str, type, other, desc, value);
18404         put_elf_reloc(symtab_section, stab_section, 
18405                       stab_section->data_offset - sizeof(unsigned long),
18406                       R_DATA_32, sym_index);
18407     }
18408     
18409     static void put_stabn(int type, int other, int desc, int value)
18410     {
18411         put_stabs(NULL, type, other, desc, value);
18412     }
18413     
18414     static void put_stabd(int type, int other, int desc)
18415     {
18416         put_stabs(NULL, type, other, desc, 0);
18417     }
18418     
18419     /* In an ELF file symbol table, the local symbols must appear below
18420        the global and weak ones. Since TCC cannot sort it while generating
18421        the code, we must do it after. All the relocation tables are also
18422        modified to take into account the symbol table sorting */
18423     static void sort_syms(TCCState *s1, Section *s)
18424     {
18425         int *old_to_new_syms;
18426         Elf32_Sym *new_syms;
18427         int nb_syms, i;
18428         Elf32_Sym *p, *q;
18429         Elf32_Rel *rel, *rel_end;
18430         Section *sr;
18431         int type, sym_index;
18432     
18433         nb_syms = s->data_offset / sizeof(Elf32_Sym);
18434         new_syms = tcc_malloc(nb_syms * sizeof(Elf32_Sym));
18435         old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
18436     
18437         /* first pass for local symbols */
18438         p = (Elf32_Sym *)s->data;
18439         q = new_syms;
18440         for(i = 0; i < nb_syms; i++) {
18441             if (ELF32_ST_BIND(p->st_info) == STB_LOCAL) {
18442                 old_to_new_syms[i] = q - new_syms;
18443                 *q++ = *p;
18444             }
18445             p++;
18446         }
18447         /* save the number of local symbols in section header */
18448         s->sh_info = q - new_syms;
18449     
18450         /* then second pass for non local symbols */
18451         p = (Elf32_Sym *)s->data;
18452         for(i = 0; i < nb_syms; i++) {
18453             if (ELF32_ST_BIND(p->st_info) != STB_LOCAL) {
18454                 old_to_new_syms[i] = q - new_syms;
18455                 *q++ = *p;
18456             }
18457             p++;
18458         }
18459         
18460         /* we copy the new symbols to the old */
18461         memcpy(s->data, new_syms, nb_syms * sizeof(Elf32_Sym));
18462         tcc_free(new_syms);
18463     
18464         /* now we modify all the relocations */
18465         for(i = 1; i < s1->nb_sections; i++) {
18466             sr = s1->sections[i];
18467             if (sr->sh_type == SHT_REL && sr->link == s) {
18468                 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
18469                 for(rel = (Elf32_Rel *)sr->data;
18470                     rel < rel_end;
18471                     rel++) {
18472                     sym_index = ELF32_R_SYM(rel->r_info);
18473                     type = ELF32_R_TYPE(rel->r_info);
18474                     sym_index = old_to_new_syms[sym_index];
18475                     rel->r_info = ELF32_R_INFO(sym_index, type);
18476                 }
18477             }
18478         }
18479         
18480         tcc_free(old_to_new_syms);
18481     }
18482     
18483     /* relocate common symbols in the .bss section */
18484     static void relocate_common_syms(void)
18485     {
18486         Elf32_Sym *sym, *sym_end;
18487         unsigned long offset, align;
18488         
18489         sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
18490         for(sym = (Elf32_Sym *)symtab_section->data + 1; 
18491             sym < sym_end;
18492             sym++) {
18493             if (sym->st_shndx == SHN_COMMON) {
18494                 /* align symbol */
18495                 align = sym->st_value;
18496                 offset = bss_section->data_offset;
18497                 offset = (offset + align - 1) & -align;
18498                 sym->st_value = offset;
18499                 sym->st_shndx = bss_section->sh_num;
18500                 offset += sym->st_size;
18501                 bss_section->data_offset = offset;
18502             }
18503         }
18504     }
18505     
18506     /* relocate symbol table, resolve undefined symbols if do_resolve is
18507        true and output error if undefined symbol. */
18508     static void relocate_syms(TCCState *s1, int do_resolve)
18509     {
18510         Elf32_Sym *sym, *esym, *sym_end;
18511         int sym_bind, sh_num, sym_index;
18512         const char *name;
18513         unsigned long addr;
18514     
18515         sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
18516         for(sym = (Elf32_Sym *)symtab_section->data + 1; 
18517             sym < sym_end;
18518             sym++) {
18519             sh_num = sym->st_shndx;
18520             if (sh_num == SHN_UNDEF) {
18521                 name = strtab_section->data + sym->st_name;
18522                 if (do_resolve) {
18523                     name = symtab_section->link->data + sym->st_name;
18524                     addr = (unsigned long)resolve_sym(s1, name, ELF32_ST_TYPE(sym->st_info));
18525                     if (addr) {
18526                         sym->st_value = addr;
18527                         goto found;
18528                     }
18529                 } else if (s1->dynsym) {
18530                     /* if dynamic symbol exist, then use it */
18531                     sym_index = find_elf_sym(s1->dynsym, name);
18532                     if (sym_index) {
18533                         esym = &((Elf32_Sym *)s1->dynsym->data)[sym_index];
18534                         sym->st_value = esym->st_value;
18535                         goto found;
18536                     }
18537                 }
18538                 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
18539                    it */
18540                 if (!strcmp(name, "_fp_hw"))
18541                     goto found;
18542                 /* only weak symbols are accepted to be undefined. Their
18543                    value is zero */
18544                 sym_bind = ELF32_ST_BIND(sym->st_info);
18545                 if (sym_bind == STB_WEAK) {
18546                     sym->st_value = 0;
18547                 } else {
18548                     error_noabort("undefined symbol '%s'", name);
18549                 }
18550             } else if (sh_num < SHN_LORESERVE) {
18551                 /* add section base */
18552                 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
18553             }
18554         found: ;
18555         }
18556     }
18557     
18558     /* relocate a given section (CPU dependent) */
18559     static void relocate_section(TCCState *s1, Section *s)
18560     {
18561         Section *sr;
18562         Elf32_Rel *rel, *rel_end, *qrel;
18563         Elf32_Sym *sym;
18564         int type, sym_index;
18565         unsigned char *ptr;
18566         unsigned long val, addr;
18567     #if defined(TCC_TARGET_I386)
18568         int esym_index;
18569     #endif
18570     
18571         sr = s->reloc;
18572         rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
18573         qrel = (Elf32_Rel *)sr->data;
18574         for(rel = qrel;
18575             rel < rel_end;
18576             rel++) {
18577             ptr = s->data + rel->r_offset;
18578     
18579             sym_index = ELF32_R_SYM(rel->r_info);
18580             sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
18581             val = sym->st_value;
18582             type = ELF32_R_TYPE(rel->r_info);
18583             addr = s->sh_addr + rel->r_offset;
18584     
18585             /* CPU specific */
18586             switch(type) {
18587     #if defined(TCC_TARGET_I386)
18588             case R_386_32:
18589                 if (s1->output_type == TCC_OUTPUT_DLL) {
18590                     esym_index = s1->symtab_to_dynsym[sym_index];
18591                     qrel->r_offset = rel->r_offset;
18592                     if (esym_index) {
18593                         qrel->r_info = ELF32_R_INFO(esym_index, R_386_32);
18594                         qrel++;
18595                         break;
18596                     } else {
18597                         qrel->r_info = ELF32_R_INFO(0, R_386_RELATIVE);
18598                         qrel++;
18599                     }
18600                 }
18601                 *(int *)ptr += val;
18602                 break;
18603             case R_386_PC32:
18604                 if (s1->output_type == TCC_OUTPUT_DLL) {
18605                     /* DLL relocation */
18606                     esym_index = s1->symtab_to_dynsym[sym_index];
18607                     if (esym_index) {
18608                         qrel->r_offset = rel->r_offset;
18609                         qrel->r_info = ELF32_R_INFO(esym_index, R_386_PC32);
18610                         qrel++;
18611                         break;
18612                     }
18613                 }
18614                 *(int *)ptr += val - addr;
18615                 break;
18616             case R_386_PLT32:
18617                 *(int *)ptr += val - addr;
18618                 break;
18619             case R_386_GLOB_DAT:
18620             case R_386_JMP_SLOT:
18621                 *(int *)ptr = val;
18622                 break;
18623             case R_386_GOTPC:
18624                 *(int *)ptr += s1->got->sh_addr - addr;
18625                 break;
18626             case R_386_GOTOFF:
18627                 *(int *)ptr += val - s1->got->sh_addr;
18628                 break;
18629             case R_386_GOT32:
18630                 /* we load the got offset */
18631                 *(int *)ptr += s1->got_offsets[sym_index];
18632                 break;
18633     #elif defined(TCC_TARGET_ARM)
18634     	case R_ARM_PC24:
18635     	case R_ARM_PLT32:
18636     	    {
18637                     int x;
18638                     x = (*(int *)ptr)&0xffffff;
18639                     (*(int *)ptr) &= 0xff000000;
18640                     if (x & 0x800000)
18641                         x -= 0x1000000;
18642                     x *= 4;
18643                     x += val - addr;
18644                     if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
18645                         error("can't relocate value at %x",addr);
18646                     x >>= 2;
18647                     x &= 0xffffff;
18648                     (*(int *)ptr) |= x;
18649     	    }
18650     	    break;
18651     	case R_ARM_ABS32:
18652     	    *(int *)ptr += val;
18653     	    break;
18654     	case R_ARM_GOTPC:
18655     	    *(int *)ptr += s1->got->sh_addr - addr;
18656     	    break;
18657             case R_ARM_GOT32:
18658                 /* we load the got offset */
18659                 *(int *)ptr += s1->got_offsets[sym_index];
18660                 break;
18661     	case R_ARM_COPY:
18662                 break;
18663     	default:
18664     	    fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
18665                         type,addr,(unsigned int )ptr,val);
18666                 break;
18667     #elif defined(TCC_TARGET_C67)
18668     	case R_C60_32:
18669     	    *(int *)ptr += val;
18670     	    break;
18671             case R_C60LO16:
18672                 {
18673                     uint32_t orig;
18674                     
18675                     /* put the low 16 bits of the absolute address */
18676                     // add to what is already there
18677                     
18678                     orig  =   ((*(int *)(ptr  )) >> 7) & 0xffff;
18679                     orig |=  (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
18680                     
18681                     //patch both at once - assumes always in pairs Low - High
18682                     
18683                     *(int *) ptr    = (*(int *) ptr    & (~(0xffff << 7)) ) |  (((val+orig)      & 0xffff) << 7);
18684                     *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
18685                 }
18686                 break;
18687             case R_C60HI16:
18688                 break;
18689             default:
18690     	    fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
18691                         type,addr,(unsigned int )ptr,val);
18692                 break;
18693     #else
18694     #error unsupported processor
18695     #endif
18696             }
18697         }
18698         /* if the relocation is allocated, we change its symbol table */
18699         if (sr->sh_flags & SHF_ALLOC)
18700             sr->link = s1->dynsym;
18701     }
18702     
18703     /* relocate relocation table in 'sr' */
18704     static void relocate_rel(TCCState *s1, Section *sr)
18705     {
18706         Section *s;
18707         Elf32_Rel *rel, *rel_end;
18708         
18709         s = s1->sections[sr->sh_info];
18710         rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
18711         for(rel = (Elf32_Rel *)sr->data;
18712             rel < rel_end;
18713             rel++) {
18714             rel->r_offset += s->sh_addr;
18715         }
18716     }
18717     
18718     /* count the number of dynamic relocations so that we can reserve
18719        their space */
18720     static int prepare_dynamic_rel(TCCState *s1, Section *sr)
18721     {
18722         Elf32_Rel *rel, *rel_end;
18723         int sym_index, esym_index, type, count;
18724     
18725         count = 0;
18726         rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
18727         for(rel = (Elf32_Rel *)sr->data; rel < rel_end; rel++) {
18728             sym_index = ELF32_R_SYM(rel->r_info);
18729             type = ELF32_R_TYPE(rel->r_info);
18730             switch(type) {
18731             case R_386_32:
18732                 count++;
18733                 break;
18734             case R_386_PC32:
18735                 esym_index = s1->symtab_to_dynsym[sym_index];
18736                 if (esym_index)
18737                     count++;
18738                 break;
18739             default:
18740                 break;
18741             }
18742         }
18743         if (count) {
18744             /* allocate the section */
18745             sr->sh_flags |= SHF_ALLOC;
18746             sr->sh_size = count * sizeof(Elf32_Rel);
18747         }
18748         return count;
18749     }
18750     
18751     static void put_got_offset(TCCState *s1, int index, unsigned long val)
18752     {
18753         int n;
18754         unsigned long *tab;
18755     
18756         if (index >= s1->nb_got_offsets) {
18757             /* find immediately bigger power of 2 and reallocate array */
18758             n = 1;
18759             while (index >= n)
18760                 n *= 2;
18761             tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
18762             if (!tab)
18763                 error("memory full");
18764             s1->got_offsets = tab;
18765             memset(s1->got_offsets + s1->nb_got_offsets, 0,
18766                    (n - s1->nb_got_offsets) * sizeof(unsigned long));
18767             s1->nb_got_offsets = n;
18768         }
18769         s1->got_offsets[index] = val;
18770     }
18771     
18772     /* XXX: suppress that */
18773     static void put32(unsigned char *p, uint32_t val)
18774     {
18775         p[0] = val;
18776         p[1] = val >> 8;
18777         p[2] = val >> 16;
18778         p[3] = val >> 24;
18779     }
18780     
18781     #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM)
18782     static uint32_t get32(unsigned char *p)
18783     {
18784         return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
18785     }
18786     #endif
18787     
18788     static void build_got(TCCState *s1)
18789     {
18790         unsigned char *ptr;
18791     
18792         /* if no got, then create it */
18793         s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
18794         s1->got->sh_entsize = 4;
18795         add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT), 
18796                     0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
18797         ptr = section_ptr_add(s1->got, 3 * sizeof(int));
18798         /* keep space for _DYNAMIC pointer, if present */
18799         put32(ptr, 0);
18800         /* two dummy got entries */
18801         put32(ptr + 4, 0);
18802         put32(ptr + 8, 0);
18803     }
18804     
18805     /* put a got entry corresponding to a symbol in symtab_section. 'size'
18806        and 'info' can be modifed if more precise info comes from the DLL */
18807     static void put_got_entry(TCCState *s1,
18808                               int reloc_type, unsigned long size, int info, 
18809                               int sym_index)
18810     {
18811         int index;
18812         const char *name;
18813         Elf32_Sym *sym;
18814         unsigned long offset;
18815         int *ptr;
18816     
18817         if (!s1->got)
18818             build_got(s1);
18819     
18820         /* if a got entry already exists for that symbol, no need to add one */
18821         if (sym_index < s1->nb_got_offsets &&
18822             s1->got_offsets[sym_index] != 0)
18823             return;
18824         
18825         put_got_offset(s1, sym_index, s1->got->data_offset);
18826     
18827         if (s1->dynsym) {
18828             sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
18829             name = symtab_section->link->data + sym->st_name;
18830             offset = sym->st_value;
18831     #ifdef TCC_TARGET_I386
18832             if (reloc_type == R_386_JMP_SLOT) {
18833                 Section *plt;
18834                 uint8_t *p;
18835                 int modrm;
18836     
18837                 /* if we build a DLL, we add a %ebx offset */
18838                 if (s1->output_type == TCC_OUTPUT_DLL)
18839                     modrm = 0xa3;
18840                 else
18841                     modrm = 0x25;
18842     
18843                 /* add a PLT entry */
18844                 plt = s1->plt;
18845                 if (plt->data_offset == 0) {
18846                     /* first plt entry */
18847                     p = section_ptr_add(plt, 16);
18848                     p[0] = 0xff; /* pushl got + 4 */
18849                     p[1] = modrm + 0x10;
18850                     put32(p + 2, 4);
18851                     p[6] = 0xff; /* jmp *(got + 8) */
18852                     p[7] = modrm;
18853                     put32(p + 8, 8);
18854                 }
18855     
18856                 p = section_ptr_add(plt, 16);
18857                 p[0] = 0xff; /* jmp *(got + x) */
18858                 p[1] = modrm;
18859                 put32(p + 2, s1->got->data_offset);
18860                 p[6] = 0x68; /* push $xxx */
18861                 put32(p + 7, (plt->data_offset - 32) >> 1);
18862                 p[11] = 0xe9; /* jmp plt_start */
18863                 put32(p + 12, -(plt->data_offset));
18864     
18865                 /* the symbol is modified so that it will be relocated to
18866                    the PLT */
18867                 if (s1->output_type == TCC_OUTPUT_EXE)
18868                     offset = plt->data_offset - 16;
18869             }
18870     #elif defined(TCC_TARGET_ARM)
18871     	if (reloc_type == R_ARM_JUMP_SLOT) {
18872                 Section *plt;
18873                 uint8_t *p;
18874                 
18875                 /* if we build a DLL, we add a %ebx offset */
18876                 if (s1->output_type == TCC_OUTPUT_DLL)
18877                     error("DLLs unimplemented!");
18878     
18879                 /* add a PLT entry */
18880                 plt = s1->plt;
18881                 if (plt->data_offset == 0) {
18882                     /* first plt entry */
18883                     p = section_ptr_add(plt, 16);
18884     		put32(p     , 0xe52de004);
18885     		put32(p +  4, 0xe59fe010);
18886     		put32(p +  8, 0xe08fe00e);
18887     		put32(p + 12, 0xe5bef008);
18888                 }
18889     
18890                 p = section_ptr_add(plt, 16);
18891     	    put32(p  , 0xe59fc004);
18892     	    put32(p+4, 0xe08fc00c);
18893     	    put32(p+8, 0xe59cf000);
18894     	    put32(p+12, s1->got->data_offset);
18895     
18896                 /* the symbol is modified so that it will be relocated to
18897                    the PLT */
18898                 if (s1->output_type == TCC_OUTPUT_EXE)
18899                     offset = plt->data_offset - 16;
18900             }
18901     #elif defined(TCC_TARGET_C67)
18902             error("C67 got not implemented");
18903     #else
18904     #error unsupported CPU
18905     #endif
18906             index = put_elf_sym(s1->dynsym, offset, 
18907                                 size, info, 0, sym->st_shndx, name);
18908             /* put a got entry */
18909             put_elf_reloc(s1->dynsym, s1->got, 
18910                           s1->got->data_offset, 
18911                           reloc_type, index);
18912         }
18913         ptr = section_ptr_add(s1->got, sizeof(int));
18914         *ptr = 0;
18915     }
18916     
18917     /* build GOT and PLT entries */
18918     static void build_got_entries(TCCState *s1)
18919     {
18920         Section *s, *symtab __attribute__((unused));
18921         Elf32_Rel *rel, *rel_end;
18922         Elf32_Sym *sym;
18923         int i, type, reloc_type, sym_index;
18924     
18925         for(i = 1; i < s1->nb_sections; i++) {
18926             s = s1->sections[i];
18927             if (s->sh_type != SHT_REL)
18928                 continue;
18929             /* no need to handle got relocations */
18930             if (s->link != symtab_section)
18931                 continue;
18932             symtab = s->link;
18933             rel_end = (Elf32_Rel *)(s->data + s->data_offset);
18934             for(rel = (Elf32_Rel *)s->data;
18935                 rel < rel_end;
18936                 rel++) {
18937                 type = ELF32_R_TYPE(rel->r_info);
18938                 switch(type) {
18939     #if defined(TCC_TARGET_I386)
18940                 case R_386_GOT32:
18941                 case R_386_GOTOFF:
18942                 case R_386_GOTPC:
18943                 case R_386_PLT32:
18944                     if (!s1->got)
18945                         build_got(s1);
18946                     if (type == R_386_GOT32 || type == R_386_PLT32) {
18947                         sym_index = ELF32_R_SYM(rel->r_info);
18948                         sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
18949                         /* look at the symbol got offset. If none, then add one */
18950                         if (type == R_386_GOT32)
18951                             reloc_type = R_386_GLOB_DAT;
18952                         else
18953                             reloc_type = R_386_JMP_SLOT;
18954                         put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 
18955                                       sym_index);
18956                     }
18957                     break;
18958     #elif defined(TCC_TARGET_ARM)
18959     	    case R_ARM_GOT32:
18960                 case R_ARM_GOTOFF:
18961                 case R_ARM_GOTPC:
18962                 case R_ARM_PLT32:
18963                     if (!s1->got)
18964                         build_got(s1);
18965                     if (type == R_ARM_GOT32 || type == R_ARM_PLT32) {
18966                         sym_index = ELF32_R_SYM(rel->r_info);
18967                         sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
18968                         /* look at the symbol got offset. If none, then add one */
18969                         if (type == R_ARM_GOT32)
18970                             reloc_type = R_ARM_GLOB_DAT;
18971                         else
18972                             reloc_type = R_ARM_JUMP_SLOT;
18973                         put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 
18974                                       sym_index);
18975                     }
18976                     break;
18977     #elif defined(TCC_TARGET_C67)
18978     	    case R_C60_GOT32:
18979                 case R_C60_GOTOFF:
18980                 case R_C60_GOTPC:
18981                 case R_C60_PLT32:
18982                     if (!s1->got)
18983                         build_got(s1);
18984                     if (type == R_C60_GOT32 || type == R_C60_PLT32) {
18985                         sym_index = ELF32_R_SYM(rel->r_info);
18986                         sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
18987                         /* look at the symbol got offset. If none, then add one */
18988                         if (type == R_C60_GOT32)
18989                             reloc_type = R_C60_GLOB_DAT;
18990                         else
18991                             reloc_type = R_C60_JMP_SLOT;
18992                         put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 
18993                                       sym_index);
18994                     }
18995                     break;
18996     #else
18997     #error unsupported CPU
18998     #endif
18999                 default:
19000                     break;
19001                 }
19002             }
19003         }
19004     }
19005     
19006     static Section *new_symtab(TCCState *s1,
19007                                const char *symtab_name, int sh_type, int sh_flags,
19008                                const char *strtab_name, 
19009                                const char *hash_name, int hash_sh_flags)
19010     {
19011         Section *symtab, *strtab, *hash;
19012         int *ptr, nb_buckets;
19013     
19014         symtab = new_section(s1, symtab_name, sh_type, sh_flags);
19015         symtab->sh_entsize = sizeof(Elf32_Sym);
19016         strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
19017         put_elf_str(strtab, "");
19018         symtab->link = strtab;
19019         put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
19020         
19021         nb_buckets = 1;
19022     
19023         hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
19024         hash->sh_entsize = sizeof(int);
19025         symtab->hash = hash;
19026         hash->link = symtab;
19027     
19028         ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
19029         ptr[0] = nb_buckets;
19030         ptr[1] = 1;
19031         memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
19032         return symtab;
19033     }
19034     
19035     /* put dynamic tag */
19036     static void put_dt(Section *dynamic, int dt, unsigned long val)
19037     {
19038         Elf32_Dyn *dyn;
19039         dyn = section_ptr_add(dynamic, sizeof(Elf32_Dyn));
19040         dyn->d_tag = dt;
19041         dyn->d_un.d_val = val;
19042     }
19043     
19044     static void add_init_array_defines(TCCState *s1, const char *section_name)
19045     {
19046         Section *s;
19047         long end_offset;
19048         char sym_start[1024];
19049         char sym_end[1024];
19050         
19051         snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
19052         snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
19053     
19054         s = find_section(s1, section_name);
19055         if (!s) {
19056             end_offset = 0;
19057             s = data_section;
19058         } else {
19059             end_offset = s->data_offset;
19060         }
19061     
19062         add_elf_sym(symtab_section, 
19063                     0, 0,
19064                     ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19065                     s->sh_num, sym_start);
19066         add_elf_sym(symtab_section, 
19067                     end_offset, 0,
19068                     ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19069                     s->sh_num, sym_end);
19070     }
19071     
19072     /* add tcc runtime libraries */
19073     static void tcc_add_runtime(TCCState *s1)
19074     {
19075         char buf[1024];
19076     
19077     #ifdef CONFIG_TCC_BCHECK
19078         if (do_bounds_check) {
19079             unsigned long *ptr;
19080             Section *init_section;
19081             unsigned char *pinit;
19082             int sym_index;
19083     
19084             /* XXX: add an object file to do that */
19085             ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
19086             *ptr = 0;
19087             add_elf_sym(symtab_section, 0, 0, 
19088                         ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19089                         bounds_section->sh_num, "__bounds_start");
19090             /* add bound check code */
19091             snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
19092             tcc_add_file(s1, buf);
19093     #ifdef TCC_TARGET_I386
19094             if (s1->output_type != TCC_OUTPUT_MEMORY) {
19095                 /* add 'call __bound_init()' in .init section */
19096                 init_section = find_section(s1, ".init");
19097                 pinit = section_ptr_add(init_section, 5);
19098                 pinit[0] = 0xe8;
19099                 put32(pinit + 1, -4);
19100                 sym_index = find_elf_sym(symtab_section, "__bound_init");
19101                 put_elf_reloc(symtab_section, init_section, 
19102                               init_section->data_offset - 4, R_386_PC32, sym_index);
19103             }
19104     #endif
19105         }
19106     #endif
19107         /* add libc */
19108         if (!s1->nostdlib) {
19109             tcc_add_library(s1, "c");
19110     
19111             snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
19112             tcc_add_file(s1, buf);
19113         }
19114         /* add crt end if not memory output */
19115         if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
19116             tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
19117         }
19118     }
19119     
19120     /* add various standard linker symbols (must be done after the
19121        sections are filled (for example after allocating common
19122        symbols)) */
19123     static void tcc_add_linker_symbols(TCCState *s1)
19124     {
19125         char buf[1024];
19126         int i;
19127         Section *s;
19128     
19129         add_elf_sym(symtab_section, 
19130                     text_section->data_offset, 0,
19131                     ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19132                     text_section->sh_num, "_etext");
19133         add_elf_sym(symtab_section, 
19134                     data_section->data_offset, 0,
19135                     ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19136                     data_section->sh_num, "_edata");
19137         add_elf_sym(symtab_section, 
19138                     bss_section->data_offset, 0,
19139                     ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19140                     bss_section->sh_num, "_end");
19141         /* horrible new standard ldscript defines */
19142         add_init_array_defines(s1, ".preinit_array");
19143         add_init_array_defines(s1, ".init_array");
19144         add_init_array_defines(s1, ".fini_array");
19145         
19146         /* add start and stop symbols for sections whose name can be
19147            expressed in C */
19148         for(i = 1; i < s1->nb_sections; i++) {
19149             s = s1->sections[i];
19150             if (s->sh_type == SHT_PROGBITS &&
19151                 (s->sh_flags & SHF_ALLOC)) {
19152                 const char *p;
19153                 int ch;
19154     
19155                 /* check if section name can be expressed in C */
19156                 p = s->name;
19157                 for(;;) {
19158                     ch = *p;
19159                     if (!ch)
19160                         break;
19161                     if (!isid(ch) && !isnum(ch))
19162                         goto next_sec;
19163                     p++;
19164                 }
19165                 snprintf(buf, sizeof(buf), "__start_%s", s->name);
19166                 add_elf_sym(symtab_section, 
19167                             0, 0,
19168                             ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19169                             s->sh_num, buf);
19170                 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
19171                 add_elf_sym(symtab_section,
19172                             s->data_offset, 0,
19173                             ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19174                             s->sh_num, buf);
19175             }
19176         next_sec: ;
19177         }
19178     }
19179     
19180     /* name of ELF interpreter */
19181     #ifdef __FreeBSD__
19182     static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
19183     #else
19184     static char elf_interp[] = "/lib/ld-linux.so.2";
19185     #endif
19186     
19187     static void tcc_output_binary(TCCState *s1, FILE *f,
19188                                   const int *section_order)
19189     {
19190         Section *s;
19191         int i, offset, size;
19192     
19193         offset = 0;
19194         for(i=1;i<s1->nb_sections;i++) {
19195             s = s1->sections[section_order[i]];
19196             if (s->sh_type != SHT_NOBITS &&
19197                 (s->sh_flags & SHF_ALLOC)) {
19198                 while (offset < s->sh_offset) {
19199                     fputc(0, f);
19200                     offset++;
19201                 }
19202                 size = s->sh_size;
19203                 dummy_size_t = fwrite(s->data, 1, size, f);
19204                 offset += size;
19205             }
19206         }
19207     }
19208     
19209     /* output an ELF file */
19210     /* XXX: suppress unneeded sections */
19211     int tcc_output_file(TCCState *s1, const char *filename)
19212     {
19213         Elf32_Ehdr ehdr;
19214         FILE *f;
19215         int fd, mode, ret;
19216         int *section_order;
19217         int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
19218         unsigned long addr;
19219         Section *strsec, *s;
19220         Elf32_Shdr shdr, *sh;
19221         Elf32_Phdr *phdr, *ph;
19222         Section *interp, *dynamic, *dynstr;
19223         unsigned long saved_dynamic_data_offset;
19224         Elf32_Sym *sym;
19225         int type, file_type;
19226         unsigned long rel_addr, rel_size;
19227         
19228         file_type = s1->output_type;
19229         s1->nb_errors = 0;
19230     
19231         if (file_type != TCC_OUTPUT_OBJ) {
19232             tcc_add_runtime(s1);
19233         }
19234     
19235         phdr = NULL;
19236         section_order = NULL;
19237         interp = NULL;
19238         dynamic = NULL;
19239         dynstr = NULL; /* avoid warning */
19240         saved_dynamic_data_offset = 0; /* avoid warning */
19241         
19242         if (file_type != TCC_OUTPUT_OBJ) {
19243             relocate_common_syms();
19244     
19245             tcc_add_linker_symbols(s1);
19246     
19247             if (!s1->static_link) {
19248                 const char *name;
19249                 int sym_index, index;
19250                 Elf32_Sym *esym, *sym_end;
19251                 
19252                 if (file_type == TCC_OUTPUT_EXE) {
19253                     char *ptr;
19254                     /* add interpreter section only if executable */
19255                     interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
19256                     interp->sh_addralign = 1;
19257                     ptr = section_ptr_add(interp, sizeof(elf_interp));
19258                     strcpy(ptr, elf_interp);
19259                 }
19260             
19261                 /* add dynamic symbol table */
19262                 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
19263                                         ".dynstr", 
19264                                         ".hash", SHF_ALLOC);
19265                 dynstr = s1->dynsym->link;
19266                 
19267                 /* add dynamic section */
19268                 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC, 
19269                                       SHF_ALLOC | SHF_WRITE);
19270                 dynamic->link = dynstr;
19271                 dynamic->sh_entsize = sizeof(Elf32_Dyn);
19272             
19273                 /* add PLT */
19274                 s1->plt = new_section(s1, ".plt", SHT_PROGBITS, 
19275                                       SHF_ALLOC | SHF_EXECINSTR);
19276                 s1->plt->sh_entsize = 4;
19277     
19278                 build_got(s1);
19279     
19280                 /* scan for undefined symbols and see if they are in the
19281                    dynamic symbols. If a symbol STT_FUNC is found, then we
19282                    add it in the PLT. If a symbol STT_OBJECT is found, we
19283                    add it in the .bss section with a suitable relocation */
19284                 sym_end = (Elf32_Sym *)(symtab_section->data + 
19285                                         symtab_section->data_offset);
19286                 if (file_type == TCC_OUTPUT_EXE) {
19287                     for(sym = (Elf32_Sym *)symtab_section->data + 1; 
19288                         sym < sym_end;
19289                         sym++) {
19290                         if (sym->st_shndx == SHN_UNDEF) {
19291                             name = symtab_section->link->data + sym->st_name;
19292                             sym_index = find_elf_sym(s1->dynsymtab_section, name);
19293                             if (sym_index) {
19294                                 esym = &((Elf32_Sym *)s1->dynsymtab_section->data)[sym_index];
19295                                 type = ELF32_ST_TYPE(esym->st_info);
19296                                 if (type == STT_FUNC) {
19297                                     put_got_entry(s1, R_JMP_SLOT, esym->st_size, 
19298                                                   esym->st_info, 
19299                                                   sym - (Elf32_Sym *)symtab_section->data);
19300                                 } else if (type == STT_OBJECT) {
19301                                     unsigned long offset;
19302                                     offset = bss_section->data_offset;
19303                                     /* XXX: which alignment ? */
19304                                     offset = (offset + 16 - 1) & -16;
19305                                     index = put_elf_sym(s1->dynsym, offset, esym->st_size, 
19306                                                         esym->st_info, 0, 
19307                                                         bss_section->sh_num, name);
19308                                     put_elf_reloc(s1->dynsym, bss_section, 
19309                                                   offset, R_COPY, index);
19310                                     offset += esym->st_size;
19311                                     bss_section->data_offset = offset;
19312                                 }
19313                             } else {
19314                                     /* STB_WEAK undefined symbols are accepted */
19315                                     /* XXX: _fp_hw seems to be part of the ABI, so we ignore
19316                                        it */
19317                                 if (ELF32_ST_BIND(sym->st_info) == STB_WEAK ||
19318                                     !strcmp(name, "_fp_hw")) {
19319                                 } else {
19320                                     error_noabort("undefined symbol '%s'", name);
19321                                 }
19322                             }
19323                         } else if (s1->rdynamic && 
19324                                    ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
19325                             /* if -rdynamic option, then export all non
19326                                local symbols */
19327                             name = symtab_section->link->data + sym->st_name;
19328                             put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, 
19329                                         sym->st_info, 0, 
19330                                         sym->st_shndx, name);
19331                         }
19332                     }
19333                 
19334                     if (s1->nb_errors)
19335                         goto fail;
19336     
19337                     /* now look at unresolved dynamic symbols and export
19338                        corresponding symbol */
19339                     sym_end = (Elf32_Sym *)(s1->dynsymtab_section->data + 
19340                                             s1->dynsymtab_section->data_offset);
19341                     for(esym = (Elf32_Sym *)s1->dynsymtab_section->data + 1; 
19342                         esym < sym_end;
19343                         esym++) {
19344                         if (esym->st_shndx == SHN_UNDEF) {
19345                             name = s1->dynsymtab_section->link->data + esym->st_name;
19346                             sym_index = find_elf_sym(symtab_section, name);
19347                             if (sym_index) {
19348                                 /* XXX: avoid adding a symbol if already
19349                                    present because of -rdynamic ? */
19350                                 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
19351                                 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, 
19352                                             sym->st_info, 0, 
19353                                             sym->st_shndx, name);
19354                             } else {
19355                                 if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) {
19356                                     /* weak symbols can stay undefined */
19357                                 } else {
19358                                     warning("undefined dynamic symbol '%s'", name);
19359                                 }
19360                             }
19361                         }
19362                     }
19363                 } else {
19364                     int nb_syms;
19365                     /* shared library case : we simply export all the global symbols */
19366                     nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
19367                     s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
19368                     for(sym = (Elf32_Sym *)symtab_section->data + 1; 
19369                         sym < sym_end;
19370                         sym++) {
19371                         if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
19372                             name = symtab_section->link->data + sym->st_name;
19373                             index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, 
19374                                                 sym->st_info, 0, 
19375                                                 sym->st_shndx, name);
19376                             s1->symtab_to_dynsym[sym - 
19377                                                 (Elf32_Sym *)symtab_section->data] = 
19378                                 index;
19379                         }
19380                     }
19381                 }
19382     
19383                 build_got_entries(s1);
19384             
19385                 /* add a list of needed dlls */
19386                 for(i = 0; i < s1->nb_loaded_dlls; i++) {
19387                     DLLReference *dllref = s1->loaded_dlls[i];
19388                     if (dllref->level == 0)
19389                         put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
19390                 }
19391                 /* XXX: currently, since we do not handle PIC code, we
19392                    must relocate the readonly segments */
19393                 if (file_type == TCC_OUTPUT_DLL)
19394                     put_dt(dynamic, DT_TEXTREL, 0);
19395     
19396                 /* add necessary space for other entries */
19397                 saved_dynamic_data_offset = dynamic->data_offset;
19398                 dynamic->data_offset += 8 * 9;
19399             } else {
19400                 /* still need to build got entries in case of static link */
19401                 build_got_entries(s1);
19402             }
19403         }
19404     
19405         memset(&ehdr, 0, sizeof(ehdr));
19406     
19407         /* we add a section for symbols */
19408         strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
19409         put_elf_str(strsec, "");
19410         
19411         /* compute number of sections */
19412         shnum = s1->nb_sections;
19413     
19414         /* this array is used to reorder sections in the output file */
19415         section_order = tcc_malloc(sizeof(int) * shnum);
19416         section_order[0] = 0;
19417         sh_order_index = 1;
19418         
19419         /* compute number of program headers */
19420         switch(file_type) {
19421         default:
19422         case TCC_OUTPUT_OBJ:
19423             phnum = 0;
19424             break;
19425         case TCC_OUTPUT_EXE:
19426             if (!s1->static_link)
19427                 phnum = 4;
19428             else
19429                 phnum = 2;
19430             break;
19431         case TCC_OUTPUT_DLL:
19432             phnum = 3;
19433             break;
19434         }
19435     
19436         /* allocate strings for section names and decide if an unallocated
19437            section should be output */
19438         /* NOTE: the strsec section comes last, so its size is also
19439            correct ! */
19440         for(i = 1; i < s1->nb_sections; i++) {
19441             s = s1->sections[i];
19442             s->sh_name = put_elf_str(strsec, s->name);
19443             /* when generating a DLL, we include relocations but we may
19444                patch them */
19445             if (file_type == TCC_OUTPUT_DLL && 
19446                 s->sh_type == SHT_REL && 
19447                 !(s->sh_flags & SHF_ALLOC)) {
19448                 prepare_dynamic_rel(s1, s);
19449             } else if (do_debug || 
19450                 file_type == TCC_OUTPUT_OBJ || 
19451                 (s->sh_flags & SHF_ALLOC) ||
19452                 i == (s1->nb_sections - 1)) {
19453                 /* we output all sections if debug or object file */
19454                 s->sh_size = s->data_offset;
19455             }
19456         }
19457     
19458         /* allocate program segment headers */
19459         phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
19460             
19461         if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
19462             file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
19463         } else {
19464             file_offset = 0;
19465         }
19466         if (phnum > 0) {
19467             /* compute section to program header mapping */
19468             if (s1->has_text_addr) { 
19469                 int a_offset, p_offset;
19470                 addr = s1->text_addr;
19471                 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
19472                    ELF_PAGE_SIZE */
19473                 a_offset = addr & (ELF_PAGE_SIZE - 1);
19474                 p_offset = file_offset & (ELF_PAGE_SIZE - 1);
19475                 if (a_offset < p_offset) 
19476                     a_offset += ELF_PAGE_SIZE;
19477                 file_offset += (a_offset - p_offset);
19478             } else {
19479                 if (file_type == TCC_OUTPUT_DLL)
19480                     addr = 0;
19481                 else
19482                     addr = ELF_START_ADDR;
19483                 /* compute address after headers */
19484                 addr += (file_offset & (ELF_PAGE_SIZE - 1));
19485             }
19486             
19487             /* dynamic relocation table information, for .dynamic section */
19488             rel_size = 0;
19489             rel_addr = 0;
19490     
19491             /* leave one program header for the program interpreter */
19492             ph = &phdr[0];
19493             if (interp)
19494                 ph++;
19495     
19496             for(j = 0; j < 2; j++) {
19497                 ph->p_type = PT_LOAD;
19498                 if (j == 0)
19499                     ph->p_flags = PF_R | PF_X;
19500                 else
19501                     ph->p_flags = PF_R | PF_W;
19502                 ph->p_align = ELF_PAGE_SIZE;
19503                 
19504                 /* we do the following ordering: interp, symbol tables,
19505                    relocations, progbits, nobits */
19506                 /* XXX: do faster and simpler sorting */
19507                 for(k = 0; k < 5; k++) {
19508                     for(i = 1; i < s1->nb_sections; i++) {
19509                         s = s1->sections[i];
19510                         /* compute if section should be included */
19511                         if (j == 0) {
19512                             if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != 
19513                                 SHF_ALLOC)
19514                                 continue;
19515                         } else {
19516                             if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != 
19517                                 (SHF_ALLOC | SHF_WRITE))
19518                                 continue;
19519                         }
19520                         if (s == interp) {
19521                             if (k != 0)
19522                                 continue;
19523                         } else if (s->sh_type == SHT_DYNSYM ||
19524                                    s->sh_type == SHT_STRTAB ||
19525                                    s->sh_type == SHT_HASH) {
19526                             if (k != 1)
19527                                 continue;
19528                         } else if (s->sh_type == SHT_REL) {
19529                             if (k != 2)
19530                                 continue;
19531                         } else if (s->sh_type == SHT_NOBITS) {
19532                             if (k != 4)
19533                                 continue;
19534                         } else {
19535                             if (k != 3)
19536                                 continue;
19537                         }
19538                         section_order[sh_order_index++] = i;
19539     
19540                         /* section matches: we align it and add its size */
19541                         tmp = addr;
19542                         addr = (addr + s->sh_addralign - 1) & 
19543                             ~(s->sh_addralign - 1);
19544                         file_offset += addr - tmp;
19545                         s->sh_offset = file_offset;
19546                         s->sh_addr = addr;
19547                         
19548                         /* update program header infos */
19549                         if (ph->p_offset == 0) {
19550                             ph->p_offset = file_offset;
19551                             ph->p_vaddr = addr;
19552                             ph->p_paddr = ph->p_vaddr;
19553                         }
19554                         /* update dynamic relocation infos */
19555                         if (s->sh_type == SHT_REL) {
19556                             if (rel_size == 0)
19557                                 rel_addr = addr;
19558                             rel_size += s->sh_size;
19559                         }
19560                         addr += s->sh_size;
19561                         if (s->sh_type != SHT_NOBITS)
19562                             file_offset += s->sh_size;
19563                     }
19564                 }
19565                 ph->p_filesz = file_offset - ph->p_offset;
19566                 ph->p_memsz = addr - ph->p_vaddr;
19567                 ph++;
19568                 if (j == 0) {
19569                     if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
19570                         /* if in the middle of a page, we duplicate the page in
19571                            memory so that one copy is RX and the other is RW */
19572                         if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
19573                             addr += ELF_PAGE_SIZE;
19574                     } else {
19575                         addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
19576                         file_offset = (file_offset + ELF_PAGE_SIZE - 1) & 
19577                             ~(ELF_PAGE_SIZE - 1);
19578                     }
19579                 }
19580             }
19581     
19582             /* if interpreter, then add corresponing program header */
19583             if (interp) {
19584                 ph = &phdr[0];
19585                 
19586                 ph->p_type = PT_INTERP;
19587                 ph->p_offset = interp->sh_offset;
19588                 ph->p_vaddr = interp->sh_addr;
19589                 ph->p_paddr = ph->p_vaddr;
19590                 ph->p_filesz = interp->sh_size;
19591                 ph->p_memsz = interp->sh_size;
19592                 ph->p_flags = PF_R;
19593                 ph->p_align = interp->sh_addralign;
19594             }
19595             
19596             /* if dynamic section, then add corresponing program header */
19597             if (dynamic) {
19598                 Elf32_Sym *sym_end;
19599     
19600                 ph = &phdr[phnum - 1];
19601                 
19602                 ph->p_type = PT_DYNAMIC;
19603                 ph->p_offset = dynamic->sh_offset;
19604                 ph->p_vaddr = dynamic->sh_addr;
19605                 ph->p_paddr = ph->p_vaddr;
19606                 ph->p_filesz = dynamic->sh_size;
19607                 ph->p_memsz = dynamic->sh_size;
19608                 ph->p_flags = PF_R | PF_W;
19609                 ph->p_align = dynamic->sh_addralign;
19610     
19611                 /* put GOT dynamic section address */
19612                 put32(s1->got->data, dynamic->sh_addr);
19613     
19614                 /* relocate the PLT */
19615                 if (file_type == TCC_OUTPUT_EXE) {
19616                     uint8_t *p, *p_end;
19617     
19618                     p = s1->plt->data;
19619                     p_end = p + s1->plt->data_offset;
19620                     if (p < p_end) {
19621     #if defined(TCC_TARGET_I386)
19622                         put32(p + 2, get32(p + 2) + s1->got->sh_addr);
19623                         put32(p + 8, get32(p + 8) + s1->got->sh_addr);
19624                         p += 16;
19625                         while (p < p_end) {
19626                             put32(p + 2, get32(p + 2) + s1->got->sh_addr);
19627                             p += 16;
19628                         }
19629     #elif defined(TCC_TARGET_ARM)
19630     		    int x;
19631     		    x=s1->got->sh_addr - s1->plt->sh_addr - 12;
19632     		    p +=16;
19633     		    while (p < p_end) {
19634     		        put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
19635     			p += 16;
19636     		    }
19637     #elif defined(TCC_TARGET_C67)
19638                         /* XXX: TODO */
19639     #else
19640     #error unsupported CPU
19641     #endif
19642                     }
19643                 }
19644     
19645                 /* relocate symbols in .dynsym */
19646                 sym_end = (Elf32_Sym *)(s1->dynsym->data + s1->dynsym->data_offset);
19647                 for(sym = (Elf32_Sym *)s1->dynsym->data + 1; 
19648                     sym < sym_end;
19649                     sym++) {
19650                     if (sym->st_shndx == SHN_UNDEF) {
19651                         /* relocate to the PLT if the symbol corresponds
19652                            to a PLT entry */
19653                         if (sym->st_value)
19654                             sym->st_value += s1->plt->sh_addr;
19655                     } else if (sym->st_shndx < SHN_LORESERVE) {
19656                         /* do symbol relocation */
19657                         sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
19658                     }
19659                 }
19660     
19661                 /* put dynamic section entries */
19662                 dynamic->data_offset = saved_dynamic_data_offset;
19663                 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
19664                 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
19665                 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
19666                 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
19667                 put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
19668                 put_dt(dynamic, DT_REL, rel_addr);
19669                 put_dt(dynamic, DT_RELSZ, rel_size);
19670                 put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
19671                 put_dt(dynamic, DT_NULL, 0);
19672             }
19673     
19674             ehdr.e_phentsize = sizeof(Elf32_Phdr);
19675             ehdr.e_phnum = phnum;
19676             ehdr.e_phoff = sizeof(Elf32_Ehdr);
19677         }
19678     
19679         /* all other sections come after */
19680         for(i = 1; i < s1->nb_sections; i++) {
19681             s = s1->sections[i];
19682             if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
19683                 continue;
19684             section_order[sh_order_index++] = i;
19685             
19686             file_offset = (file_offset + s->sh_addralign - 1) & 
19687                 ~(s->sh_addralign - 1);
19688             s->sh_offset = file_offset;
19689             if (s->sh_type != SHT_NOBITS)
19690                 file_offset += s->sh_size;
19691         }
19692         
19693         /* if building executable or DLL, then relocate each section
19694            except the GOT which is already relocated */
19695         if (file_type != TCC_OUTPUT_OBJ) {
19696             relocate_syms(s1, 0);
19697     
19698             if (s1->nb_errors != 0) {
19699             fail:
19700                 ret = -1;
19701                 goto the_end;
19702             }
19703     
19704             /* relocate sections */
19705             /* XXX: ignore sections with allocated relocations ? */
19706             for(i = 1; i < s1->nb_sections; i++) {
19707                 s = s1->sections[i];
19708                 if (s->reloc && s != s1->got)
19709                     relocate_section(s1, s);
19710             }
19711     
19712             /* relocate relocation entries if the relocation tables are
19713                allocated in the executable */
19714             for(i = 1; i < s1->nb_sections; i++) {
19715                 s = s1->sections[i];
19716                 if ((s->sh_flags & SHF_ALLOC) &&
19717                     s->sh_type == SHT_REL) {
19718                     relocate_rel(s1, s);
19719                 }
19720             }
19721     
19722             /* get entry point address */
19723             if (file_type == TCC_OUTPUT_EXE)
19724                 ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start");
19725             else
19726                 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
19727         }
19728     
19729         /* write elf file */
19730         if (file_type == TCC_OUTPUT_OBJ)
19731             mode = 0666;
19732         else
19733             mode = 0777;
19734         fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode); 
19735         if (fd < 0) {
19736             error_noabort("could not write '%s'", filename);
19737             goto fail;
19738         }
19739         f = fdopen(fd, "wb");
19740     
19741     #ifdef TCC_TARGET_COFF
19742         if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
19743             tcc_output_coff(s1, f);
19744         } else
19745     #endif
19746         if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
19747             sort_syms(s1, symtab_section);
19748             
19749             /* align to 4 */
19750             file_offset = (file_offset + 3) & -4;
19751         
19752             /* fill header */
19753             ehdr.e_ident[0] = ELFMAG0;
19754             ehdr.e_ident[1] = ELFMAG1;
19755             ehdr.e_ident[2] = ELFMAG2;
19756             ehdr.e_ident[3] = ELFMAG3;
19757             ehdr.e_ident[4] = ELFCLASS32;
19758             ehdr.e_ident[5] = ELFDATA2LSB;
19759             ehdr.e_ident[6] = EV_CURRENT;
19760     #ifdef __FreeBSD__
19761             ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
19762     #endif
19763     #ifdef TCC_TARGET_ARM
19764             ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
19765     #endif
19766             switch(file_type) {
19767             default:
19768             case TCC_OUTPUT_EXE:
19769                 ehdr.e_type = ET_EXEC;
19770                 break;
19771             case TCC_OUTPUT_DLL:
19772                 ehdr.e_type = ET_DYN;
19773                 break;
19774             case TCC_OUTPUT_OBJ:
19775                 ehdr.e_type = ET_REL;
19776                 break;
19777             }
19778             ehdr.e_machine = EM_TCC_TARGET;
19779             ehdr.e_version = EV_CURRENT;
19780             ehdr.e_shoff = file_offset;
19781             ehdr.e_ehsize = sizeof(Elf32_Ehdr);
19782             ehdr.e_shentsize = sizeof(Elf32_Shdr);
19783             ehdr.e_shnum = shnum;
19784             ehdr.e_shstrndx = shnum - 1;
19785             
19786             dummy_size_t = fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
19787             dummy_size_t = fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
19788             offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
19789     
19790             for(i=1;i<s1->nb_sections;i++) {
19791                 s = s1->sections[section_order[i]];
19792                 if (s->sh_type != SHT_NOBITS) {
19793                     while (offset < s->sh_offset) {
19794                         fputc(0, f);
19795                         offset++;
19796                     }
19797                     size = s->sh_size;
19798                     dummy_size_t = fwrite(s->data, 1, size, f);
19799                     offset += size;
19800                 }
19801             }
19802     
19803             /* output section headers */
19804             while (offset < ehdr.e_shoff) {
19805                 fputc(0, f);
19806                 offset++;
19807             }
19808         
19809             for(i=0;i<s1->nb_sections;i++) {
19810                 sh = &shdr;
19811                 memset(sh, 0, sizeof(Elf32_Shdr));
19812                 s = s1->sections[i];
19813                 if (s) {
19814                     sh->sh_name = s->sh_name;
19815                     sh->sh_type = s->sh_type;
19816                     sh->sh_flags = s->sh_flags;
19817                     sh->sh_entsize = s->sh_entsize;
19818                     sh->sh_info = s->sh_info;
19819                     if (s->link)
19820                         sh->sh_link = s->link->sh_num;
19821                     sh->sh_addralign = s->sh_addralign;
19822                     sh->sh_addr = s->sh_addr;
19823                     sh->sh_offset = s->sh_offset;
19824                     sh->sh_size = s->sh_size;
19825                 }
19826                 dummy_size_t = fwrite(sh, 1, sizeof(Elf32_Shdr), f);
19827             }
19828         } else {
19829             tcc_output_binary(s1, f, section_order);
19830         }
19831         fclose(f);
19832     
19833         ret = 0;
19834      the_end:
19835         tcc_free(s1->symtab_to_dynsym);
19836         tcc_free(section_order);
19837         tcc_free(phdr);
19838         tcc_free(s1->got_offsets);
19839         return ret;
19840     }
19841     
19842     static void *load_data(int fd, unsigned long file_offset, unsigned long size)
19843     {
19844         void *data;
19845     
19846         data = tcc_malloc(size);
19847         lseek(fd, file_offset, SEEK_SET);
19848         dummy_size_t = read(fd, data, size);
19849         return data;
19850     }
19851     
19852     typedef struct SectionMergeInfo {
19853         Section *s;            /* corresponding existing section */
19854         unsigned long offset;  /* offset of the new section in the existing section */
19855         uint8_t new_section;       /* true if section 's' was added */
19856         uint8_t link_once;         /* true if link once section */
19857     } SectionMergeInfo;
19858     
19859     /* load an object file and merge it with current files */
19860     /* XXX: handle correctly stab (debug) info */
19861     static int tcc_load_object_file(TCCState *s1, 
19862                                     int fd, unsigned long file_offset)
19863     { 
19864         Elf32_Ehdr ehdr;
19865         Elf32_Shdr *shdr, *sh;
19866         int size, i, j, offset, offseti, nb_syms, sym_index, ret;
19867         unsigned char *strsec, *strtab;
19868         int *old_to_new_syms;
19869         char *sh_name, *name;
19870         SectionMergeInfo *sm_table, *sm;
19871         Elf32_Sym *sym, *symtab;
19872         Elf32_Rel *rel, *rel_end;
19873         Section *s;
19874     
19875         if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
19876             goto fail1;
19877         if (ehdr.e_ident[0] != ELFMAG0 ||
19878             ehdr.e_ident[1] != ELFMAG1 ||
19879             ehdr.e_ident[2] != ELFMAG2 ||
19880             ehdr.e_ident[3] != ELFMAG3)
19881             goto fail1;
19882         /* test if object file */
19883         if (ehdr.e_type != ET_REL)
19884             goto fail1;
19885         /* test CPU specific stuff */
19886         if (ehdr.e_ident[5] != ELFDATA2LSB ||
19887             ehdr.e_machine != EM_TCC_TARGET) {
19888         fail1:
19889             error_noabort("invalid object file");
19890             return -1;
19891         }
19892         /* read sections */
19893         shdr = load_data(fd, file_offset + ehdr.e_shoff, 
19894                          sizeof(Elf32_Shdr) * ehdr.e_shnum);
19895         sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
19896         
19897         /* load section names */
19898         sh = &shdr[ehdr.e_shstrndx];
19899         strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
19900     
19901         /* load symtab and strtab */
19902         old_to_new_syms = NULL;
19903         symtab = NULL;
19904         strtab = NULL;
19905         nb_syms = 0;
19906         for(i = 1; i < ehdr.e_shnum; i++) {
19907             sh = &shdr[i];
19908             if (sh->sh_type == SHT_SYMTAB) {
19909                 if (symtab) {
19910                     error_noabort("object must contain only one symtab");
19911                 fail:
19912                     ret = -1;
19913                     goto the_end;
19914                 }
19915                 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
19916                 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
19917                 sm_table[i].s = symtab_section;
19918     
19919                 /* now load strtab */
19920                 sh = &shdr[sh->sh_link];
19921                 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
19922             }
19923         }
19924             
19925         /* now examine each section and try to merge its content with the
19926            ones in memory */
19927         for(i = 1; i < ehdr.e_shnum; i++) {
19928             /* no need to examine section name strtab */
19929             if (i == ehdr.e_shstrndx)
19930                 continue;
19931             sh = &shdr[i];
19932             sh_name = strsec + sh->sh_name;
19933             /* ignore sections types we do not handle */
19934             if (sh->sh_type != SHT_PROGBITS &&
19935                 sh->sh_type != SHT_REL && 
19936                 sh->sh_type != SHT_NOBITS)
19937                 continue;
19938             if (sh->sh_addralign < 1)
19939                 sh->sh_addralign = 1;
19940             /* find corresponding section, if any */
19941             for(j = 1; j < s1->nb_sections;j++) {
19942                 s = s1->sections[j];
19943                 if (!strcmp(s->name, sh_name)) {
19944                     if (!strncmp(sh_name, ".gnu.linkonce", 
19945                                  sizeof(".gnu.linkonce") - 1)) {
19946                         /* if a 'linkonce' section is already present, we
19947                            do not add it again. It is a little tricky as
19948                            symbols can still be defined in
19949                            it. */
19950                         sm_table[i].link_once = 1;
19951                         goto next;
19952                     } else {
19953                         goto found;
19954                     }
19955                 }
19956             }
19957             /* not found: create new section */
19958             s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
19959             /* take as much info as possible from the section. sh_link and
19960                sh_info will be updated later */
19961             s->sh_addralign = sh->sh_addralign;
19962             s->sh_entsize = sh->sh_entsize;
19963             sm_table[i].new_section = 1;
19964         found:
19965             if (sh->sh_type != s->sh_type) {
19966                 error_noabort("invalid section type");
19967                 goto fail;
19968             }
19969     
19970             /* align start of section */
19971             offset = s->data_offset;
19972             size = sh->sh_addralign - 1;
19973             offset = (offset + size) & ~size;
19974             if (sh->sh_addralign > s->sh_addralign)
19975                 s->sh_addralign = sh->sh_addralign;
19976             s->data_offset = offset;
19977             sm_table[i].offset = offset;
19978             sm_table[i].s = s;
19979             /* concatenate sections */
19980             size = sh->sh_size;
19981             if (sh->sh_type != SHT_NOBITS) {
19982                 unsigned char *ptr;
19983                 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
19984                 ptr = section_ptr_add(s, size);
19985                 dummy_size_t = read(fd, ptr, size);
19986             } else {
19987                 s->data_offset += size;
19988             }
19989         next: ;
19990         }
19991     
19992         /* second short pass to update sh_link and sh_info fields of new
19993            sections */
19994         sm = sm_table;
19995         for(i = 1; i < ehdr.e_shnum; i++) {
19996             s = sm_table[i].s;
19997             if (!s || !sm_table[i].new_section)
19998                 continue;
19999             sh = &shdr[i];
20000             if (sh->sh_link > 0)
20001                 s->link = sm_table[sh->sh_link].s;
20002             if (sh->sh_type == SHT_REL) {
20003                 s->sh_info = sm_table[sh->sh_info].s->sh_num;
20004                 /* update backward link */
20005                 s1->sections[s->sh_info]->reloc = s;
20006             }
20007         }
20008     
20009         /* resolve symbols */
20010         old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
20011     
20012         sym = symtab + 1;
20013         for(i = 1; i < nb_syms; i++, sym++) {
20014             if (sym->st_shndx != SHN_UNDEF &&
20015                 sym->st_shndx < SHN_LORESERVE) {
20016                 sm = &sm_table[sym->st_shndx];
20017                 if (sm->link_once) {
20018                     /* if a symbol is in a link once section, we use the
20019                        already defined symbol. It is very important to get
20020                        correct relocations */
20021                     if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
20022                         name = strtab + sym->st_name;
20023                         sym_index = find_elf_sym(symtab_section, name);
20024                         if (sym_index)
20025                             old_to_new_syms[i] = sym_index;
20026                     }
20027                     continue;
20028                 }
20029                 /* if no corresponding section added, no need to add symbol */
20030                 if (!sm->s)
20031                     continue;
20032                 /* convert section number */
20033                 sym->st_shndx = sm->s->sh_num;
20034                 /* offset value */
20035                 sym->st_value += sm->offset;
20036             }
20037             /* add symbol */
20038             name = strtab + sym->st_name;
20039             sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size, 
20040                                     sym->st_info, sym->st_other, 
20041                                     sym->st_shndx, name);
20042             old_to_new_syms[i] = sym_index;
20043         }
20044     
20045         /* third pass to patch relocation entries */
20046         for(i = 1; i < ehdr.e_shnum; i++) {
20047             s = sm_table[i].s;
20048             if (!s)
20049                 continue;
20050             sh = &shdr[i];
20051             offset = sm_table[i].offset;
20052             switch(s->sh_type) {
20053             case SHT_REL:
20054                 /* take relocation offset information */
20055                 offseti = sm_table[sh->sh_info].offset;
20056                 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
20057                 for(rel = (Elf32_Rel *)(s->data + offset);
20058                     rel < rel_end;
20059                     rel++) {
20060                     int type;
20061                     unsigned sym_index;
20062                     /* convert symbol index */
20063                     type = ELF32_R_TYPE(rel->r_info);
20064                     sym_index = ELF32_R_SYM(rel->r_info);
20065                     /* NOTE: only one symtab assumed */
20066                     if (sym_index >= nb_syms)
20067                         goto invalid_reloc;
20068                     sym_index = old_to_new_syms[sym_index];
20069                     if (!sym_index) {
20070                     invalid_reloc:
20071                         error_noabort("Invalid relocation entry");
20072                         goto fail;
20073                     }
20074                     rel->r_info = ELF32_R_INFO(sym_index, type);
20075                     /* offset the relocation offset */
20076                     rel->r_offset += offseti;
20077                 }
20078                 break;
20079             default:
20080                 break;
20081             }
20082         }
20083         
20084         ret = 0;
20085      the_end:
20086         tcc_free(symtab);
20087         tcc_free(strtab);
20088         tcc_free(old_to_new_syms);
20089         tcc_free(sm_table);
20090         tcc_free(strsec);
20091         tcc_free(shdr);
20092         return ret;
20093     }
20094     
20095     #define ARMAG  "!<arch>\012"	/* For COFF and a.out archives */
20096     
20097     typedef struct ArchiveHeader {
20098         char ar_name[16];		/* name of this member */
20099         char ar_date[12];		/* file mtime */
20100         char ar_uid[6];		/* owner uid; printed as decimal */
20101         char ar_gid[6];		/* owner gid; printed as decimal */
20102         char ar_mode[8];		/* file mode, printed as octal   */
20103         char ar_size[10];		/* file size, printed as decimal */
20104         char ar_fmag[2];		/* should contain ARFMAG */
20105     } ArchiveHeader;
20106     
20107     static int get_be32(const uint8_t *b)
20108     {
20109         return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
20110     }
20111     
20112     /* load only the objects which resolve undefined symbols */
20113     static int tcc_load_alacarte(TCCState *s1, int fd, int size)
20114     {
20115         int i, bound, nsyms, sym_index, off, ret;
20116         uint8_t *data;
20117         const char *ar_names, *p;
20118         const uint8_t *ar_index;
20119         Elf32_Sym *sym;
20120     
20121         data = tcc_malloc(size);
20122         if (read(fd, data, size) != size)
20123             goto fail;
20124         nsyms = get_be32(data);
20125         ar_index = data + 4;
20126         ar_names = ar_index + nsyms * 4;
20127     
20128         do {
20129     	bound = 0;
20130     	for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
20131     	    sym_index = find_elf_sym(symtab_section, p);
20132     	    if(sym_index) {
20133     		sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
20134     		if(sym->st_shndx == SHN_UNDEF) {
20135     		    off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
20136     #if 0
20137     		    printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
20138     #endif
20139     		    ++bound;
20140     		    lseek(fd, off, SEEK_SET);
20141     		    if(tcc_load_object_file(s1, fd, off) < 0) {
20142                         fail:
20143                             ret = -1;
20144                             goto the_end;
20145                         }
20146     		}
20147     	    }
20148     	}
20149         } while(bound);
20150         ret = 0;
20151      the_end:
20152         tcc_free(data);
20153         return ret;
20154     }
20155     
20156     /* load a '.a' file */
20157     static int tcc_load_archive(TCCState *s1, int fd)
20158     {
20159         ArchiveHeader hdr;
20160         char ar_size[11];
20161         char ar_name[17];
20162         char magic[8];
20163         int size, len, i;
20164         unsigned long file_offset;
20165     
20166         /* skip magic which was already checked */
20167         dummy_size_t = read(fd, magic, sizeof(magic));
20168         
20169         for(;;) {
20170             len = read(fd, &hdr, sizeof(hdr));
20171             if (len == 0)
20172                 break;
20173             if (len != sizeof(hdr)) {
20174                 error_noabort("invalid archive");
20175                 return -1;
20176             }
20177             memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
20178             ar_size[sizeof(hdr.ar_size)] = '\0';
20179             size = strtol(ar_size, NULL, 0);
20180             memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
20181             for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
20182                 if (ar_name[i] != ' ')
20183                     break;
20184             }
20185             ar_name[i + 1] = '\0';
20186             //        printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
20187             file_offset = lseek(fd, 0, SEEK_CUR);
20188             /* align to even */
20189             size = (size + 1) & ~1;
20190             if (!strcmp(ar_name, "/")) {
20191                 /* coff symbol table : we handle it */
20192     	    if(s1->alacarte_link)
20193     		return tcc_load_alacarte(s1, fd, size);
20194             } else if (!strcmp(ar_name, "//") ||
20195                        !strcmp(ar_name, "__.SYMDEF") ||
20196                        !strcmp(ar_name, "__.SYMDEF/") ||
20197                        !strcmp(ar_name, "ARFILENAMES/")) {
20198                 /* skip symbol table or archive names */
20199             } else {
20200                 if (tcc_load_object_file(s1, fd, file_offset) < 0)
20201                     return -1;
20202             }
20203             lseek(fd, file_offset + size, SEEK_SET);
20204         }
20205         return 0;
20206     }
20207     
20208     /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
20209        is referenced by the user (so it should be added as DT_NEEDED in
20210        the generated ELF file) */
20211     static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
20212     { 
20213         Elf32_Ehdr ehdr;
20214         Elf32_Shdr *shdr, *sh, *sh1;
20215         int i, nb_syms, nb_dts, sym_bind, ret;
20216         Elf32_Sym *sym, *dynsym;
20217         Elf32_Dyn *dt, *dynamic;
20218         unsigned char *dynstr;
20219         const char *name, *soname, *p;
20220         DLLReference *dllref;
20221         
20222         dummy_size_t = read(fd, &ehdr, sizeof(ehdr));
20223     
20224         /* test CPU specific stuff */
20225         if (ehdr.e_ident[5] != ELFDATA2LSB ||
20226             ehdr.e_machine != EM_TCC_TARGET) {
20227             error_noabort("bad architecture");
20228             return -1;
20229         }
20230     
20231         /* read sections */
20232         shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
20233     
20234         /* load dynamic section and dynamic symbols */
20235         nb_syms = 0;
20236         nb_dts = 0;
20237         dynamic = NULL;
20238         dynsym = NULL; /* avoid warning */
20239         dynstr = NULL; /* avoid warning */
20240         for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
20241             switch(sh->sh_type) {
20242             case SHT_DYNAMIC:
20243                 nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
20244                 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
20245                 break;
20246             case SHT_DYNSYM:
20247                 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
20248                 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
20249                 sh1 = &shdr[sh->sh_link];
20250                 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
20251                 break;
20252             default:
20253                 break;
20254             }
20255         }
20256         
20257         /* compute the real library name */
20258         soname = filename;
20259         p = strrchr(soname, '/');
20260         if (p)
20261             soname = p + 1;
20262             
20263         for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
20264             if (dt->d_tag == DT_SONAME) {
20265                 soname = dynstr + dt->d_un.d_val;
20266             }
20267         }
20268     
20269         /* if the dll is already loaded, do not load it */
20270         for(i = 0; i < s1->nb_loaded_dlls; i++) {
20271             dllref = s1->loaded_dlls[i];
20272             if (!strcmp(soname, dllref->name)) {
20273                 /* but update level if needed */
20274                 if (level < dllref->level)
20275                     dllref->level = level;
20276                 ret = 0;
20277                 goto the_end;
20278             }
20279         }
20280         
20281         //    printf("loading dll '%s'\n", soname);
20282     
20283         /* add the dll and its level */
20284         dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname));
20285         dllref->level = level;
20286         strcpy(dllref->name, soname);
20287         dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
20288     
20289         /* add dynamic symbols in dynsym_section */
20290         for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
20291             sym_bind = ELF32_ST_BIND(sym->st_info);
20292             if (sym_bind == STB_LOCAL)
20293                 continue;
20294             name = dynstr + sym->st_name;
20295             add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
20296                         sym->st_info, sym->st_other, sym->st_shndx, name);
20297         }
20298     
20299         /* load all referenced DLLs */
20300         for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
20301             switch(dt->d_tag) {
20302             case DT_NEEDED:
20303                 name = dynstr + dt->d_un.d_val;
20304                 for(i = 0; i < s1->nb_loaded_dlls; i++) {
20305                     dllref = s1->loaded_dlls[i];
20306                     if (!strcmp(name, dllref->name))
20307                         goto already_loaded;
20308                 }
20309                 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
20310                     error_noabort("referenced dll '%s' not found", name);
20311                     ret = -1;
20312                     goto the_end;
20313                 }
20314             already_loaded:
20315                 break;
20316             }
20317         }
20318         ret = 0;
20319      the_end:
20320         tcc_free(dynstr);
20321         tcc_free(dynsym);
20322         tcc_free(dynamic);
20323         tcc_free(shdr);
20324         return ret;
20325     }
20326     
20327     #define LD_TOK_NAME 256
20328     #define LD_TOK_EOF  (-1)
20329     
20330     /* return next ld script token */
20331     static int ld_next(TCCState *s1, char *name, int name_size)
20332     {
20333         int c;
20334         char *q;
20335     
20336      redo:
20337         switch(ch) {
20338         case ' ':
20339         case '\t':
20340         case '\f':
20341         case '\v':
20342         case '\r':
20343         case '\n':
20344             inp();
20345             goto redo;
20346         case '/':
20347             minp();
20348             if (ch == '*') {
20349                 file->buf_ptr = parse_comment(file->buf_ptr);
20350                 ch = file->buf_ptr[0];
20351                 goto redo;
20352             } else {
20353                 q = name;
20354                 *q++ = '/';
20355                 goto parse_name;
20356             }
20357             break;
20358         case 'a' ... 'z':
20359         case 'A' ... 'Z':
20360         case '_':
20361         case '\\':
20362         case '.':
20363         case '$':
20364         case '~':
20365             q = name;
20366         parse_name:
20367             for(;;) {
20368                 if (!((ch >= 'a' && ch <= 'z') ||
20369                       (ch >= 'A' && ch <= 'Z') ||
20370                       (ch >= '0' && ch <= '9') ||
20371                       strchr("/.-_+=$:\\,~", ch)))
20372                     break;
20373                 if ((q - name) < name_size - 1) {
20374                     *q++ = ch;
20375                 }
20376                 minp();
20377             }
20378             *q = '\0';
20379             c = LD_TOK_NAME;
20380             break;
20381         case CH_EOF:
20382             c = LD_TOK_EOF;
20383             break;
20384         default:
20385             c = ch;
20386             inp();
20387             break;
20388         }
20389     #if 0
20390         printf("tok=%c %d\n", c, c);
20391         if (c == LD_TOK_NAME)
20392             printf("  name=%s\n", name);
20393     #endif
20394         return c;
20395     }
20396     
20397     /* interpret a subset of GNU ldscripts to handle the dummy libc.so
20398        files */
20399     static int tcc_load_ldscript(TCCState *s1)
20400     {
20401         char cmd[64];
20402         char filename[1024];
20403         int t;
20404         
20405         ch = file->buf_ptr[0];
20406         ch = handle_eob();
20407         for(;;) {
20408             t = ld_next(s1, cmd, sizeof(cmd));
20409             if (t == LD_TOK_EOF)
20410                 return 0;
20411             else if (t != LD_TOK_NAME)
20412                 return -1;
20413             if (!strcmp(cmd, "INPUT") ||
20414                 !strcmp(cmd, "GROUP")) {
20415                 t = ld_next(s1, cmd, sizeof(cmd));
20416                 if (t != '(')
20417                     expect("(");
20418                 t = ld_next(s1, filename, sizeof(filename));
20419                 for(;;) {
20420                     if (t == LD_TOK_EOF) {
20421                         error_noabort("unexpected end of file");
20422                         return -1;
20423                     } else if (t == ')') {
20424                         break;
20425                     } else if (t != LD_TOK_NAME) {
20426                         error_noabort("filename expected");
20427                         return -1;
20428                     } 
20429                     tcc_add_file(s1, filename);
20430                     t = ld_next(s1, filename, sizeof(filename));
20431                     if (t == ',') {
20432                         t = ld_next(s1, filename, sizeof(filename));
20433                     }
20434                 }
20435             } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
20436                        !strcmp(cmd, "TARGET")) {
20437                 /* ignore some commands */
20438                 t = ld_next(s1, cmd, sizeof(cmd));
20439                 if (t != '(')
20440                     expect("(");
20441                 for(;;) {
20442                     t = ld_next(s1, filename, sizeof(filename));
20443                     if (t == LD_TOK_EOF) {
20444                         error_noabort("unexpected end of file");
20445                         return -1;
20446                     } else if (t == ')') {
20447                         break;
20448                     }
20449                 }
20450             } else {
20451                 return -1;
20452             }
20453         }
20454         return 0;
20455     }
20456     //---------------------------------------------------------------------------
20457     
20458     #ifdef TCC_TARGET_COFF
20459     #include "tcccoff.c"
20460     #endif
20461     
20462     #ifdef TCC_TARGET_PE
20463     #include "tccpe.c"
20464     #endif
20465     
20466     /* print the position in the source file of PC value 'pc' by reading
20467        the stabs debug information */
20468     static void rt_printline(unsigned long wanted_pc)
20469     {
20470         Stab_Sym *sym, *sym_end;
20471         char func_name[128], last_func_name[128];
20472         unsigned long func_addr, last_pc, pc;
20473         const char *incl_files[INCLUDE_STACK_SIZE];
20474         int incl_index, len, last_line_num, i;
20475         const char *str, *p;
20476     
20477         fprintf(stderr, "0x%08lx:", wanted_pc);
20478     
20479         func_name[0] = '\0';
20480         func_addr = 0;
20481         incl_index = 0;
20482         last_func_name[0] = '\0';
20483         last_pc = 0xffffffff;
20484         last_line_num = 1;
20485         sym = (Stab_Sym *)stab_section->data + 1;
20486         sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
20487         while (sym < sym_end) {
20488             switch(sym->n_type) {
20489                 /* function start or end */
20490             case N_FUN:
20491                 if (sym->n_strx == 0) {
20492                     /* we test if between last line and end of function */
20493                     pc = sym->n_value + func_addr;
20494                     if (wanted_pc >= last_pc && wanted_pc < pc)
20495                         goto found;
20496                     func_name[0] = '\0';
20497                     func_addr = 0;
20498                 } else {
20499                     str = stabstr_section->data + sym->n_strx;
20500                     p = strchr(str, ':');
20501                     if (!p) {
20502                         pstrcpy(func_name, sizeof(func_name), str);
20503                     } else {
20504                         len = p - str;
20505                         if (len > sizeof(func_name) - 1)
20506                             len = sizeof(func_name) - 1;
20507                         memcpy(func_name, str, len);
20508                         func_name[len] = '\0';
20509                     }
20510                     func_addr = sym->n_value;
20511                 }
20512                 break;
20513                 /* line number info */
20514             case N_SLINE:
20515                 pc = sym->n_value + func_addr;
20516                 if (wanted_pc >= last_pc && wanted_pc < pc)
20517                     goto found;
20518                 last_pc = pc;
20519                 last_line_num = sym->n_desc;
20520                 /* XXX: slow! */
20521                 strcpy(last_func_name, func_name);
20522                 break;
20523                 /* include files */
20524             case N_BINCL:
20525                 str = stabstr_section->data + sym->n_strx;
20526             add_incl:
20527                 if (incl_index < INCLUDE_STACK_SIZE) {
20528                     incl_files[incl_index++] = str;
20529                 }
20530                 break;
20531             case N_EINCL:
20532                 if (incl_index > 1)
20533                     incl_index--;
20534                 break;
20535             case N_SO:
20536                 if (sym->n_strx == 0) {
20537                     incl_index = 0; /* end of translation unit */
20538                 } else {
20539                     str = stabstr_section->data + sym->n_strx;
20540                     /* do not add path */
20541                     len = strlen(str);
20542                     if (len > 0 && str[len - 1] != '/')
20543                         goto add_incl;
20544                 }
20545                 break;
20546             }
20547             sym++;
20548         }
20549     
20550         /* second pass: we try symtab symbols (no line number info) */
20551         incl_index = 0;
20552         {
20553             Elf32_Sym *sym, *sym_end;
20554             int type;
20555     
20556             sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
20557             for(sym = (Elf32_Sym *)symtab_section->data + 1; 
20558                 sym < sym_end;
20559                 sym++) {
20560                 type = ELF32_ST_TYPE(sym->st_info);
20561                 if (type == STT_FUNC) {
20562                     if (wanted_pc >= sym->st_value &&
20563                         wanted_pc < sym->st_value + sym->st_size) {
20564                         pstrcpy(last_func_name, sizeof(last_func_name),
20565                                 strtab_section->data + sym->st_name);
20566                         goto found;
20567                     }
20568                 }
20569             }
20570         }
20571         /* did not find any info: */
20572         fprintf(stderr, " ???\n");
20573         return;
20574      found:
20575         if (last_func_name[0] != '\0') {
20576             fprintf(stderr, " %s()", last_func_name);
20577         }
20578         if (incl_index > 0) {
20579             fprintf(stderr, " (%s:%d", 
20580                     incl_files[incl_index - 1], last_line_num);
20581             for(i = incl_index - 2; i >= 0; i--)
20582                 fprintf(stderr, ", included from %s", incl_files[i]);
20583             fprintf(stderr, ")");
20584         }
20585         fprintf(stderr, "\n");
20586     }
20587     
20588     #if !defined(WIN32) && !defined(CONFIG_TCCBOOT)
20589     
20590     /* return the PC at frame level 'level'. Return non zero if not found */
20591     static int rt_get_caller_pc(unsigned long *paddr, 
20592                                 ucontext_t *uc, int level)
20593     {
20594         unsigned long fp __attribute__((unused));
20595         //int i;
20596     
20597         if (level == 0) {
20598             *paddr = 12345; //uc->uc_mcontext.gregs[REG_EIP];
20599             return 0;
20600         } else {
20601             fp = 23456; //uc->uc_mcontext.gregs[REG_EBP];
20602             return 0;
20603         }
20604     }
20605     
20606     /* emit a run time error at position 'pc' */
20607     void rt_error(ucontext_t *uc, const char *fmt, ...)
20608     {
20609         va_list ap;
20610         unsigned long pc = 0;  // shut gcc up
20611         int i;
20612     
20613         va_start(ap, fmt);
20614         fprintf(stderr, "Runtime error: ");
20615         vfprintf(stderr, fmt, ap);
20616         fprintf(stderr, "\n");
20617         for(i=0;i<num_callers;i++) {
20618             if (rt_get_caller_pc(&pc, uc, i) < 0)
20619                 break;
20620             if (i == 0)
20621                 fprintf(stderr, "at ");
20622             else
20623                 fprintf(stderr, "by ");
20624             rt_printline(pc);
20625         }
20626         exit(255);
20627         va_end(ap);
20628     }
20629     
20630     /* signal handler for fatal errors */
20631     static void sig_error(int signum, siginfo_t *siginf, void *puc)
20632     {
20633         ucontext_t *uc = puc;
20634     
20635         switch(signum) {
20636         case SIGFPE:
20637             switch(siginf->si_code) {
20638             case FPE_INTDIV:
20639             case FPE_FLTDIV:
20640                 rt_error(uc, "division by zero");
20641                 break;
20642             default:
20643                 rt_error(uc, "floating point exception");
20644                 break;
20645             }
20646             break;
20647         case SIGBUS:
20648         case SIGSEGV:
20649             if (rt_bound_error_msg && *rt_bound_error_msg)
20650                 rt_error(uc, *rt_bound_error_msg);
20651             else
20652                 rt_error(uc, "dereferencing invalid pointer");
20653             break;
20654         case SIGILL:
20655             rt_error(uc, "illegal instruction");
20656             break;
20657         case SIGABRT:
20658             rt_error(uc, "abort() called");
20659             break;
20660         default:
20661             rt_error(uc, "caught signal %d", signum);
20662             break;
20663         }
20664         exit(255);
20665     }
20666     #endif
20667     
20668     /* do all relocations (needed before using tcc_get_symbol()) */
20669     int tcc_relocate(TCCState *s1)
20670     {
20671         Section *s;
20672         int i;
20673     
20674         s1->nb_errors = 0;
20675         
20676     #ifdef TCC_TARGET_PE
20677         pe_add_runtime(s1);
20678     #else
20679         tcc_add_runtime(s1);
20680     #endif
20681     
20682         relocate_common_syms();
20683     
20684         tcc_add_linker_symbols(s1);
20685     
20686         build_got_entries(s1);
20687         
20688         /* compute relocation address : section are relocated in place. We
20689            also alloc the bss space */
20690         for(i = 1; i < s1->nb_sections; i++) {
20691             s = s1->sections[i];
20692             if (s->sh_flags & SHF_ALLOC) {
20693                 if (s->sh_type == SHT_NOBITS)
20694                     s->data = tcc_mallocz(s->data_offset);
20695                 s->sh_addr = (unsigned long)s->data;
20696             }
20697         }
20698     
20699         relocate_syms(s1, 1);
20700     
20701         if (s1->nb_errors != 0)
20702             return -1;
20703     
20704         /* relocate each section */
20705         for(i = 1; i < s1->nb_sections; i++) {
20706             s = s1->sections[i];
20707             if (s->reloc)
20708                 relocate_section(s1, s);
20709         }
20710         return 0;
20711     }
20712     
20713     /* launch the compiled program with the given arguments */
20714     int tcc_run(TCCState *s1, int argc, char **argv)
20715     {
20716         int (*prog_main)(int, char **);
20717     
20718         if (tcc_relocate(s1) < 0)
20719             return -1;
20720     
20721         prog_main = tcc_get_symbol_err(s1, "main");
20722         
20723         if (do_debug) {
20724     #if defined(WIN32) || defined(CONFIG_TCCBOOT)
20725             error("debug mode currently not available for Windows");
20726     #else        
20727             struct sigaction sigact;
20728             /* install TCC signal handlers to print debug info on fatal
20729                runtime errors */
20730             sigact.sa_flags = SA_SIGINFO | SA_RESETHAND;
20731             sigact.sa_sigaction = sig_error;
20732             sigemptyset(&sigact.sa_mask);
20733             sigaction(SIGFPE, &sigact, NULL);
20734             sigaction(SIGILL, &sigact, NULL);
20735             sigaction(SIGSEGV, &sigact, NULL);
20736             sigaction(SIGBUS, &sigact, NULL);
20737             sigaction(SIGABRT, &sigact, NULL);
20738     #endif
20739         }
20740     
20741     #ifdef CONFIG_TCC_BCHECK
20742         if (do_bounds_check) {
20743             void (*bound_init)(void);
20744     
20745             /* set error function */
20746             rt_bound_error_msg = (void *)tcc_get_symbol_err(s1, 
20747                                                             "__bound_error_msg");
20748     
20749             /* XXX: use .init section so that it also work in binary ? */
20750             bound_init = (void *)tcc_get_symbol_err(s1, "__bound_init");
20751             bound_init();
20752         }
20753     #endif
20754         return (*prog_main)(argc, argv);
20755     }
20756     
20757     TCCState *tcc_new(void)
20758     {
20759         const char *p, *r;
20760         TCCState *s;
20761         TokenSym *ts __attribute__((unused));
20762         int i, c;
20763     
20764         s = tcc_mallocz(sizeof(TCCState));
20765         if (!s)
20766             return NULL;
20767         tcc_state = s;
20768         s->output_type = TCC_OUTPUT_MEMORY;
20769     
20770         /* init isid table */
20771         for(i=0;i<256;i++)
20772             isidnum_table[i] = isid(i) || isnum(i);
20773     
20774         /* add all tokens */
20775         table_ident = NULL;
20776         memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
20777         
20778         tok_ident = TOK_IDENT;
20779         p = tcc_keywords;
20780         while (*p) {
20781             r = p;
20782             for(;;) {
20783                 c = *r++;
20784                 if (c == '\0')
20785                     break;
20786             }
20787             ts = tok_alloc(p, r - p - 1);
20788             p = r;
20789         }
20790     
20791         /* we add dummy defines for some special macros to speed up tests
20792            and to have working defined() */
20793         define_push(TOK___LINE__, MACRO_OBJ, NULL, NULL);
20794         define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
20795         define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
20796         define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
20797     
20798         /* standard defines */
20799         tcc_define_symbol(s, "__STDC__", NULL);
20800     #if defined(TCC_TARGET_I386)
20801         tcc_define_symbol(s, "__i386__", NULL);
20802     #endif
20803     #if defined(TCC_TARGET_ARM)
20804         tcc_define_symbol(s, "__ARM_ARCH_4__", NULL);
20805         tcc_define_symbol(s, "__arm_elf__", NULL);
20806         tcc_define_symbol(s, "__arm_elf", NULL);
20807         tcc_define_symbol(s, "arm_elf", NULL);
20808         tcc_define_symbol(s, "__arm__", NULL);
20809         tcc_define_symbol(s, "__arm", NULL);
20810         tcc_define_symbol(s, "arm", NULL);
20811         tcc_define_symbol(s, "__APCS_32__", NULL);
20812     #endif
20813     #if defined(linux)
20814         tcc_define_symbol(s, "__linux__", NULL);
20815         tcc_define_symbol(s, "linux", NULL);
20816     #endif
20817         /* tiny C specific defines */
20818         tcc_define_symbol(s, "__TINYC__", NULL);
20819     
20820         /* tiny C & gcc defines */
20821         tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int");
20822         tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int");
20823         tcc_define_symbol(s, "__WCHAR_TYPE__", "int");
20824         
20825         /* default library paths */
20826     #ifdef TCC_TARGET_PE
20827         {
20828             char buf[1024];
20829             snprintf(buf, sizeof(buf), "%s/lib", tcc_lib_path);
20830             tcc_add_library_path(s, buf);
20831         }
20832     #else
20833         tcc_add_library_path(s, "/usr/local/lib");
20834         tcc_add_library_path(s, "/usr/lib");
20835         tcc_add_library_path(s, "/lib");
20836     #endif
20837     
20838         /* no section zero */
20839         dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
20840     
20841         /* create standard sections */
20842         text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
20843         data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
20844         bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
20845     
20846         /* symbols are always generated for linking stage */
20847         symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
20848                                     ".strtab",
20849                                     ".hashtab", SHF_PRIVATE); 
20850         strtab_section = symtab_section->link;
20851         
20852         /* private symbol table for dynamic symbols */
20853         s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
20854                                           ".dynstrtab", 
20855                                           ".dynhashtab", SHF_PRIVATE);
20856         s->alacarte_link = 1;
20857     
20858     #ifdef CHAR_IS_UNSIGNED
20859         s->char_is_unsigned = 1;
20860     #endif
20861     #if defined(TCC_TARGET_PE) && 0
20862         /* XXX: currently the PE linker is not ready to support that */
20863         s->leading_underscore = 1;
20864     #endif
20865         return s;
20866     }
20867     
20868     void tcc_delete(TCCState *s1)
20869     {
20870         int i, n;
20871     
20872         /* free -D defines */
20873         free_defines(NULL);
20874     
20875         /* free tokens */
20876         n = tok_ident - TOK_IDENT;
20877         for(i = 0; i < n; i++)
20878             tcc_free(table_ident[i]);
20879         tcc_free(table_ident);
20880     
20881         /* free all sections */
20882     
20883         free_section(symtab_section->hash);
20884     
20885         free_section(s1->dynsymtab_section->hash);
20886         free_section(s1->dynsymtab_section->link);
20887         free_section(s1->dynsymtab_section);
20888     
20889         for(i = 1; i < s1->nb_sections; i++)
20890             free_section(s1->sections[i]);
20891         tcc_free(s1->sections);
20892         
20893         /* free loaded dlls array */
20894         for(i = 0; i < s1->nb_loaded_dlls; i++)
20895             tcc_free(s1->loaded_dlls[i]);
20896         tcc_free(s1->loaded_dlls);
20897     
20898         /* library paths */
20899         for(i = 0; i < s1->nb_library_paths; i++)
20900             tcc_free(s1->library_paths[i]);
20901         tcc_free(s1->library_paths);
20902     
20903         /* cached includes */
20904         for(i = 0; i < s1->nb_cached_includes; i++)
20905             tcc_free(s1->cached_includes[i]);
20906         tcc_free(s1->cached_includes);
20907     
20908         for(i = 0; i < s1->nb_include_paths; i++)
20909             tcc_free(s1->include_paths[i]);
20910         tcc_free(s1->include_paths);
20911     
20912         for(i = 0; i < s1->nb_sysinclude_paths; i++)
20913             tcc_free(s1->sysinclude_paths[i]);
20914         tcc_free(s1->sysinclude_paths);
20915     
20916         tcc_free(s1);
20917     }
20918     
20919     int tcc_add_include_path(TCCState *s1, const char *pathname)
20920     {
20921         char *pathname1;
20922         
20923         pathname1 = tcc_strdup(pathname);
20924         dynarray_add((void ***)&s1->include_paths, &s1->nb_include_paths, pathname1);
20925         return 0;
20926     }
20927     
20928     int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
20929     {
20930         char *pathname1;
20931         
20932         pathname1 = tcc_strdup(pathname);
20933         dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1);
20934         return 0;
20935     }
20936     
20937     static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
20938     {
20939         const char *ext, *filename1;
20940         Elf32_Ehdr ehdr;
20941         int fd, ret;
20942         BufferedFile *saved_file;
20943     
20944         /* find source file type with extension */
20945         filename1 = strrchr(filename, '/');
20946         if (filename1)
20947             filename1++;
20948         else
20949             filename1 = filename;
20950         ext = strrchr(filename1, '.');
20951         if (ext)
20952             ext++;
20953     
20954         /* open the file */
20955         saved_file = file;
20956         file = tcc_open(s1, filename);
20957         if (!file) {
20958             if (flags & AFF_PRINT_ERROR) {
20959                 error_noabort("file '%s' not found", filename);
20960             }
20961             ret = -1;
20962             goto fail1;
20963         }
20964     
20965         if (!ext || !strcmp(ext, "c")) {
20966             /* C file assumed */
20967             ret = tcc_compile(s1);
20968         } else 
20969     #ifdef CONFIG_TCC_ASM
20970         if (!strcmp(ext, "S")) {
20971             /* preprocessed assembler */
20972             ret = tcc_assemble(s1, 1);
20973         } else if (!strcmp(ext, "s")) {
20974             /* non preprocessed assembler */
20975             ret = tcc_assemble(s1, 0);
20976         } else 
20977     #endif
20978     #ifdef TCC_TARGET_PE
20979         if (!strcmp(ext, "def")) {
20980             ret = pe_load_def_file(s1, fdopen(file->fd, "rb"));
20981         } else
20982     #endif
20983         {
20984             fd = file->fd;
20985             /* assume executable format: auto guess file type */
20986             ret = read(fd, &ehdr, sizeof(ehdr));
20987             lseek(fd, 0, SEEK_SET);
20988             if (ret <= 0) {
20989                 error_noabort("could not read header");
20990                 goto fail;
20991             } else if (ret != sizeof(ehdr)) {
20992                 goto try_load_script;
20993             }
20994     
20995             if (ehdr.e_ident[0] == ELFMAG0 &&
20996                 ehdr.e_ident[1] == ELFMAG1 &&
20997                 ehdr.e_ident[2] == ELFMAG2 &&
20998                 ehdr.e_ident[3] == ELFMAG3) {
20999                 file->line_num = 0; /* do not display line number if error */
21000                 if (ehdr.e_type == ET_REL) {
21001                     ret = tcc_load_object_file(s1, fd, 0);
21002                 } else if (ehdr.e_type == ET_DYN) {
21003                     if (s1->output_type == TCC_OUTPUT_MEMORY) {
21004     #ifdef TCC_TARGET_PE
21005                         ret = -1;
21006     #else
21007                         void *h;
21008     		    assert(0);
21009     		    h = 0;
21010                         //h = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);
21011     		    // jrs: remove need for dlopen
21012                         if (h)
21013                             ret = 0;
21014                         else
21015                             ret = -1;
21016     #endif
21017                     } else {
21018                         ret = tcc_load_dll(s1, fd, filename, 
21019                                            (flags & AFF_REFERENCED_DLL) != 0);
21020                     }
21021                 } else {
21022                     error_noabort("unrecognized ELF file");
21023                     goto fail;
21024                 }
21025             } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
21026                 file->line_num = 0; /* do not display line number if error */
21027                 ret = tcc_load_archive(s1, fd);
21028             } else 
21029     #ifdef TCC_TARGET_COFF
21030             if (*(uint16_t *)(&ehdr) == COFF_C67_MAGIC) {
21031                 ret = tcc_load_coff(s1, fd);
21032             } else
21033     #endif
21034             {
21035                 /* as GNU ld, consider it is an ld script if not recognized */
21036             try_load_script:
21037                 ret = tcc_load_ldscript(s1);
21038                 if (ret < 0) {
21039                     error_noabort("unrecognized file type");
21040                     goto fail;
21041                 }
21042             }
21043         }
21044      the_end:
21045         tcc_close(file);
21046      fail1:
21047         file = saved_file;
21048         return ret;
21049      fail:
21050         ret = -1;
21051         goto the_end;
21052     }
21053     
21054     int tcc_add_file(TCCState *s, const char *filename)
21055     {
21056         return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
21057     }
21058     
21059     int tcc_add_library_path(TCCState *s, const char *pathname)
21060     {
21061         char *pathname1;
21062         
21063         pathname1 = tcc_strdup(pathname);
21064         dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, pathname1);
21065         return 0;
21066     }
21067     
21068     /* find and load a dll. Return non zero if not found */
21069     /* XXX: add '-rpath' option support ? */
21070     static int tcc_add_dll(TCCState *s, const char *filename, int flags)
21071     {
21072         char buf[1024];
21073         int i;
21074     
21075         for(i = 0; i < s->nb_library_paths; i++) {
21076             snprintf(buf, sizeof(buf), "%s/%s", 
21077                      s->library_paths[i], filename);
21078             if (tcc_add_file_internal(s, buf, flags) == 0)
21079                 return 0;
21080         }
21081         return -1;
21082     }
21083     
21084     /* the library name is the same as the argument of the '-l' option */
21085     int tcc_add_library(TCCState *s, const char *libraryname)
21086     {
21087         char buf[1024];
21088         int i;
21089         
21090         /* first we look for the dynamic library if not static linking */
21091         if (!s->static_link) {
21092     #ifdef TCC_TARGET_PE
21093             snprintf(buf, sizeof(buf), "%s.def", libraryname);
21094     #else
21095             snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
21096     #endif
21097             if (tcc_add_dll(s, buf, 0) == 0)
21098                 return 0;
21099         }
21100     
21101         /* then we look for the static library */
21102         for(i = 0; i < s->nb_library_paths; i++) {
21103             snprintf(buf, sizeof(buf), "%s/lib%s.a", 
21104                      s->library_paths[i], libraryname);
21105             if (tcc_add_file_internal(s, buf, 0) == 0)
21106                 return 0;
21107         }
21108         return -1;
21109     }
21110     
21111     int tcc_add_symbol(TCCState *s, const char *name, unsigned long val)
21112     {
21113         add_elf_sym(symtab_section, val, 0, 
21114                     ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
21115                     SHN_ABS, name);
21116         return 0;
21117     }
21118     
21119     int tcc_set_output_type(TCCState *s, int output_type)
21120     {
21121         s->output_type = output_type;
21122     
21123         if (!s->nostdinc) {
21124             char buf[1024];
21125     
21126             /* default include paths */
21127             /* XXX: reverse order needed if -isystem support */
21128     #ifndef TCC_TARGET_PE
21129             tcc_add_sysinclude_path(s, "/usr/local/include");
21130             tcc_add_sysinclude_path(s, "/usr/include");
21131     #endif
21132             snprintf(buf, sizeof(buf), "%s/include", tcc_lib_path);
21133             tcc_add_sysinclude_path(s, buf);
21134     #ifdef TCC_TARGET_PE
21135             snprintf(buf, sizeof(buf), "%s/include/winapi", tcc_lib_path);
21136             tcc_add_sysinclude_path(s, buf);
21137     #endif
21138         }
21139     
21140         /* if bound checking, then add corresponding sections */
21141     #ifdef CONFIG_TCC_BCHECK
21142         if (do_bounds_check) {
21143             /* define symbol */
21144             tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
21145             /* create bounds sections */
21146             bounds_section = new_section(s, ".bounds", 
21147                                          SHT_PROGBITS, SHF_ALLOC);
21148             lbounds_section = new_section(s, ".lbounds", 
21149                                           SHT_PROGBITS, SHF_ALLOC);
21150         }
21151     #endif
21152     
21153         if (s->char_is_unsigned) {
21154             tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL);
21155         }
21156     
21157         /* add debug sections */
21158         if (do_debug) {
21159             /* stab symbols */
21160             stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
21161             stab_section->sh_entsize = sizeof(Stab_Sym);
21162             stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
21163             put_elf_str(stabstr_section, "");
21164             stab_section->link = stabstr_section;
21165             /* put first entry */
21166             put_stabs("", 0, 0, 0, 0);
21167         }
21168     
21169         /* add libc crt1/crti objects */
21170     #ifndef TCC_TARGET_PE
21171         if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&
21172             !s->nostdlib) {
21173             if (output_type != TCC_OUTPUT_DLL)
21174                 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
21175             tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
21176         }
21177     #endif
21178         return 0;
21179     }
21180     
21181     #define WD_ALL    0x0001 /* warning is activated when using -Wall */
21182     #define FD_INVERT 0x0002 /* invert value before storing */
21183     
21184     typedef struct FlagDef {
21185         uint16_t offset;
21186         uint16_t flags;
21187         const char *name;
21188     } FlagDef;
21189     
21190     static const FlagDef warning_defs[] = {
21191         { offsetof(TCCState, warn_unsupported), 0, "unsupported" },
21192         { offsetof(TCCState, warn_write_strings), 0, "write-strings" },
21193         { offsetof(TCCState, warn_error), 0, "error" },
21194         { offsetof(TCCState, warn_implicit_function_declaration), WD_ALL,
21195           "implicit-function-declaration" },
21196     };
21197     
21198     static int set_flag(TCCState *s, const FlagDef *flags, int nb_flags,
21199                         const char *name, int value)
21200     {
21201         int i;
21202         const FlagDef *p;
21203         const char *r;
21204     
21205         r = name;
21206         if (r[0] == 'n' && r[1] == 'o' && r[2] == '-') {
21207             r += 3;
21208             value = !value;
21209         }
21210         for(i = 0, p = flags; i < nb_flags; i++, p++) {
21211             if (!strcmp(r, p->name))
21212                 goto found;
21213         }
21214         return -1;
21215      found:
21216         if (p->flags & FD_INVERT)
21217             value = !value;
21218         *(int *)((uint8_t *)s + p->offset) = value;
21219         return 0;
21220     }
21221     
21222     
21223     /* set/reset a warning */
21224     int tcc_set_warning(TCCState *s, const char *warning_name, int value)
21225     {
21226         int i;
21227         const FlagDef *p;
21228     
21229         if (!strcmp(warning_name, "all")) {
21230             for(i = 0, p = warning_defs; i < countof(warning_defs); i++, p++) {
21231                 if (p->flags & WD_ALL)
21232                     *(int *)((uint8_t *)s + p->offset) = 1;
21233             }
21234             return 0;
21235         } else {
21236             return set_flag(s, warning_defs, countof(warning_defs),
21237                             warning_name, value);
21238         }
21239     }
21240     
21241     static const FlagDef flag_defs[] = {
21242         { offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" },
21243         { offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" },
21244         { offsetof(TCCState, nocommon), FD_INVERT, "common" },
21245         { offsetof(TCCState, leading_underscore), 0, "leading-underscore" },
21246     };
21247     
21248     /* set/reset a flag */
21249     int tcc_set_flag(TCCState *s, const char *flag_name, int value)
21250     {
21251         return set_flag(s, flag_defs, countof(flag_defs),
21252                         flag_name, value);
21253     }
21254     
21255     #if !defined(LIBTCC)
21256     
21257     /* extract the basename of a file */
21258     static const char *tcc_basename(const char *name)
21259     {
21260         const char *p;
21261         p = strrchr(name, '/');
21262     #ifdef WIN32
21263         if (!p)
21264             p = strrchr(name, '\\');
21265     #endif    
21266         if (!p)
21267             p = name;
21268         else 
21269             p++;
21270         return p;
21271     }
21272     
21273     static int64_t getclock_us(void)
21274     {
21275     #ifdef WIN32
21276         struct _timeb tb;
21277         _ftime(&tb);
21278         return (tb.time * 1000LL + tb.millitm) * 1000LL;
21279     #else
21280         struct timeval tv;
21281         gettimeofday(&tv, NULL);
21282         return tv.tv_sec * 1000000LL + tv.tv_usec;
21283     #endif
21284     }
21285     
21286     void help(void)
21287     {
21288         printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001-2010 Fabrice Bellard\n"
21289                "usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
21290                "           [-Wwarn] [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
21291                "           [infile1 infile2...] [-run infile args...]\n"
21292                "\n"
21293                "General options:\n"
21294                "  -v          display current version\n"
21295                "  -c          compile only - generate an object file\n"
21296                "  -o outfile  set output filename\n"
21297                "  -Bdir       set tcc internal library path\n"
21298                "  -bench      output compilation statistics\n"
21299      	   "  -run        run compiled source\n"
21300                "  -fflag      set or reset (with 'no-' prefix) 'flag' (see man page)\n"
21301                "  -Wwarning   set or reset (with 'no-' prefix) 'warning' (see man page)\n"
21302                "  -w          disable all warnings\n"
21303                "Preprocessor options:\n"
21304                "  -Idir       add include path 'dir'\n"
21305                "  -Dsym[=val] define 'sym' with value 'val'\n"
21306                "  -Usym       undefine 'sym'\n"
21307                "Linker options:\n"
21308                "  -Ldir       add library path 'dir'\n"
21309                "  -llib       link with dynamic or static library 'lib'\n"
21310                "  -shared     generate a shared library\n"
21311                "  -static     static linking\n"
21312                "  -rdynamic   export all global symbols to dynamic linker\n"
21313                "  -r          relocatable output\n"
21314                "Debugger options:\n"
21315                "  -g          generate runtime debug info\n"
21316     #ifdef CONFIG_TCC_BCHECK
21317                "  -b          compile with built-in memory and bounds checker (implies -g)\n"
21318     #endif
21319                "  -bt N       show N callers in stack traces\n"
21320                );
21321     }
21322     
21323     #define TCC_OPTION_HAS_ARG 0x0001
21324     #define TCC_OPTION_NOSEP   0x0002 /* cannot have space before option and arg */
21325     
21326     typedef struct TCCOption {
21327         const char *name;
21328         uint16_t index;
21329         uint16_t flags;
21330     } TCCOption;
21331     
21332     enum {
21333         TCC_OPTION_HELP,
21334         TCC_OPTION_I,
21335         TCC_OPTION_D,
21336         TCC_OPTION_U,
21337         TCC_OPTION_L,
21338         TCC_OPTION_B,
21339         TCC_OPTION_l,
21340         TCC_OPTION_bench,
21341         TCC_OPTION_bt,
21342         TCC_OPTION_b,
21343         TCC_OPTION_g,
21344         TCC_OPTION_c,
21345         TCC_OPTION_static,
21346         TCC_OPTION_shared,
21347         TCC_OPTION_o,
21348         TCC_OPTION_r,
21349         TCC_OPTION_Wl,
21350         TCC_OPTION_W,
21351         TCC_OPTION_O,
21352         TCC_OPTION_m,
21353         TCC_OPTION_f,
21354         TCC_OPTION_nostdinc,
21355         TCC_OPTION_nostdlib,
21356         TCC_OPTION_print_search_dirs,
21357         TCC_OPTION_rdynamic,
21358         TCC_OPTION_run,
21359         TCC_OPTION_v,
21360         TCC_OPTION_w,
21361         TCC_OPTION_pipe,
21362     };
21363     
21364     static const TCCOption tcc_options[] = {
21365         { "h", TCC_OPTION_HELP, 0 },
21366         { "?", TCC_OPTION_HELP, 0 },
21367         { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG },
21368         { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG },
21369         { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG },
21370         { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG },
21371         { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG },
21372         { "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21373         { "bench", TCC_OPTION_bench, 0 },
21374         { "bt", TCC_OPTION_bt, TCC_OPTION_HAS_ARG },
21375     #ifdef CONFIG_TCC_BCHECK
21376         { "b", TCC_OPTION_b, 0 },
21377     #endif
21378         { "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21379         { "c", TCC_OPTION_c, 0 },
21380         { "static", TCC_OPTION_static, 0 },
21381         { "shared", TCC_OPTION_shared, 0 },
21382         { "o", TCC_OPTION_o, TCC_OPTION_HAS_ARG },
21383         { "run", TCC_OPTION_run, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21384         { "rdynamic", TCC_OPTION_rdynamic, 0 },
21385         { "r", TCC_OPTION_r, 0 },
21386         { "Wl,", TCC_OPTION_Wl, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21387         { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21388         { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21389         { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG },
21390         { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21391         { "nostdinc", TCC_OPTION_nostdinc, 0 },
21392         { "nostdlib", TCC_OPTION_nostdlib, 0 },
21393         { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 }, 
21394         { "v", TCC_OPTION_v, 0 },
21395         { "w", TCC_OPTION_w, 0 },
21396         { "pipe", TCC_OPTION_pipe, 0},
21397         { NULL },
21398     };
21399     
21400     /* convert 'str' into an array of space separated strings */
21401     static int expand_args(char ***pargv, const char *str)
21402     {
21403         const char *s1;
21404         char **argv, *arg;
21405         int argc, len;
21406     
21407         argc = 0;
21408         argv = NULL;
21409         for(;;) {
21410             while (is_space(*str))
21411                 str++;
21412             if (*str == '\0')
21413                 break;
21414             s1 = str;
21415             while (*str != '\0' && !is_space(*str))
21416                 str++;
21417             len = str - s1;
21418             arg = tcc_malloc(len + 1);
21419             memcpy(arg, s1, len);
21420             arg[len] = '\0';
21421             dynarray_add((void ***)&argv, &argc, arg);
21422         }
21423         *pargv = argv;
21424         return argc;
21425     }
21426     
21427     static char **files;
21428     static int nb_files, nb_libraries;
21429     static int multiple_files;
21430     static int print_search_dirs;
21431     static int output_type;
21432     static int reloc_output;
21433     static const char *outfile;
21434     
21435     int parse_args(TCCState *s, int argc, char **argv)
21436     {
21437         int optind;
21438         const TCCOption *popt;
21439         const char *optarg, *p1, *r1;
21440         char *r;
21441     
21442         optind = 0;
21443         while (1) {
21444             if (optind >= argc) {
21445                 if (nb_files == 0 && !print_search_dirs)
21446                     goto show_help;
21447                 else
21448                     break;
21449             }
21450             r = argv[optind++];
21451             if (r[0] != '-') {
21452                 /* add a new file */
21453                 dynarray_add((void ***)&files, &nb_files, r);
21454                 if (!multiple_files) {
21455                     optind--;
21456                     /* argv[0] will be this file */
21457                     break;
21458                 }
21459             } else {
21460                 /* find option in table (match only the first chars */
21461                 popt = tcc_options;
21462                 for(;;) {
21463                     p1 = popt->name;
21464                     if (p1 == NULL)
21465                         error("invalid option -- '%s'", r);
21466                     r1 = r + 1;
21467                     for(;;) {
21468                         if (*p1 == '\0')
21469                             goto option_found;
21470                         if (*r1 != *p1)
21471                             break;
21472                         p1++;
21473                         r1++;
21474                     }
21475                     popt++;
21476                 }
21477             option_found:
21478                 if (popt->flags & TCC_OPTION_HAS_ARG) {
21479                     if (*r1 != '\0' || (popt->flags & TCC_OPTION_NOSEP)) {
21480                         optarg = r1;
21481                     } else {
21482                         if (optind >= argc)
21483                             error("argument to '%s' is missing", r);
21484                         optarg = argv[optind++];
21485                     }
21486                 } else {
21487                     if (*r1 != '\0')
21488                         goto show_help;
21489                     optarg = NULL;
21490                 }
21491                     
21492                 switch(popt->index) {
21493                 case TCC_OPTION_HELP:
21494                 show_help:
21495                     help();
21496                     exit(1);
21497                 case TCC_OPTION_I:
21498                     if (tcc_add_include_path(s, optarg) < 0)
21499                         error("too many include paths");
21500                     break;
21501                 case TCC_OPTION_D:
21502                     {
21503                         char *sym, *value;
21504                         sym = (char *)optarg;
21505                         value = strchr(sym, '=');
21506                         if (value) {
21507                             *value = '\0';
21508                             value++;
21509                         }
21510                         tcc_define_symbol(s, sym, value);
21511                     }
21512                     break;
21513                 case TCC_OPTION_U:
21514                     tcc_undefine_symbol(s, optarg);
21515                     break;
21516                 case TCC_OPTION_L:
21517                     tcc_add_library_path(s, optarg);
21518                     break;
21519                 case TCC_OPTION_B:
21520                     /* set tcc utilities path (mainly for tcc development) */
21521                     tcc_lib_path = optarg;
21522                     break;
21523                 case TCC_OPTION_l:
21524                     dynarray_add((void ***)&files, &nb_files, r);
21525                     nb_libraries++;
21526                     break;
21527                 case TCC_OPTION_bench:
21528                     do_bench = 1;
21529                     break;
21530                 case TCC_OPTION_bt:
21531                     num_callers = atoi(optarg);
21532                     break;
21533     #ifdef CONFIG_TCC_BCHECK
21534                 case TCC_OPTION_b:
21535                     do_bounds_check = 1;
21536                     do_debug = 1;
21537                     break;
21538     #endif
21539                 case TCC_OPTION_g:
21540                     do_debug = 1;
21541                     break;
21542                 case TCC_OPTION_c:
21543                     multiple_files = 1;
21544                     output_type = TCC_OUTPUT_OBJ;
21545                     break;
21546                 case TCC_OPTION_static:
21547                     s->static_link = 1;
21548                     break;
21549                 case TCC_OPTION_shared:
21550                     output_type = TCC_OUTPUT_DLL;
21551                     break;
21552                 case TCC_OPTION_o:
21553                     multiple_files = 1;
21554                     outfile = optarg;
21555                     break;
21556                 case TCC_OPTION_r:
21557                     /* generate a .o merging several output files */
21558                     reloc_output = 1;
21559                     output_type = TCC_OUTPUT_OBJ;
21560                     break;
21561                 case TCC_OPTION_nostdinc:
21562                     s->nostdinc = 1;
21563                     break;
21564                 case TCC_OPTION_nostdlib:
21565                     s->nostdlib = 1;
21566                     break;
21567                 case TCC_OPTION_print_search_dirs:
21568                     print_search_dirs = 1;
21569                     break;
21570                 case TCC_OPTION_run:
21571                     {
21572                         int argc1;
21573                         char **argv1;
21574                         argc1 = expand_args(&argv1, optarg);
21575                         if (argc1 > 0) {
21576                             parse_args(s, argc1, argv1);
21577                         }
21578                         multiple_files = 0;
21579                         output_type = TCC_OUTPUT_MEMORY;
21580                     }
21581                     break;
21582                 case TCC_OPTION_v:
21583                     printf("tcc version %s\n", TCC_VERSION);
21584                     exit(0);
21585                 case TCC_OPTION_f:
21586                     if (tcc_set_flag(s, optarg, 1) < 0 && s->warn_unsupported)
21587                         goto unsupported_option;
21588                     break;
21589                 case TCC_OPTION_W:
21590                     if (tcc_set_warning(s, optarg, 1) < 0 && 
21591                         s->warn_unsupported)
21592                         goto unsupported_option;
21593                     break;
21594                 case TCC_OPTION_w:
21595                     s->warn_none = 1;
21596                     break;
21597                 case TCC_OPTION_rdynamic:
21598                     s->rdynamic = 1;
21599                     break;
21600                 case TCC_OPTION_Wl:
21601                     {
21602                         const char *p;
21603                         if (strstart(optarg, "-Ttext,", &p)) {
21604                             s->text_addr = strtoul(p, NULL, 16);
21605                             s->has_text_addr = 1;
21606                         } else if (strstart(optarg, "--oformat,", &p)) {
21607                             if (strstart(p, "elf32-", NULL)) {
21608                                 s->output_format = TCC_OUTPUT_FORMAT_ELF;
21609                             } else if (!strcmp(p, "binary")) {
21610                                 s->output_format = TCC_OUTPUT_FORMAT_BINARY;
21611                             } else
21612     #ifdef TCC_TARGET_COFF
21613                             if (!strcmp(p, "coff")) {
21614                                 s->output_format = TCC_OUTPUT_FORMAT_COFF;
21615                             } else
21616     #endif
21617                             {
21618                                 error("target %s not found", p);
21619                             }
21620                         } else {
21621                             error("unsupported linker option '%s'", optarg);
21622                         }
21623                     }
21624                     break;
21625                 default:
21626                     if (s->warn_unsupported) {
21627                     unsupported_option:
21628                         warning("unsupported option '%s'", r);
21629                     }
21630                     break;
21631                 }
21632             }
21633         }
21634         return optind;
21635     }
21636     
21637     // njn: renamed main() as main2() in order to repeat it multiple times.
21638     int main2(int argc, char **argv)
21639     {
21640         int i;
21641         TCCState *s;
21642         int nb_objfiles, ret, optind;
21643         char objfilename[1024];
21644         int64_t start_time = 0;
21645     
21646     #ifdef WIN32
21647         /* on win32, we suppose the lib and includes are at the location
21648            of 'tcc.exe' */
21649         {
21650             static char path[1024];
21651             char *p, *d;
21652             
21653             GetModuleFileNameA(NULL, path, sizeof path);
21654             p = d = strlwr(path);
21655             while (*d)
21656             {
21657                 if (*d == '\\') *d = '/', p = d;
21658                 ++d;
21659             }
21660             *p = '\0';
21661             tcc_lib_path = path;
21662         }
21663     #endif
21664     
21665         s = tcc_new();
21666         output_type = TCC_OUTPUT_EXE;
21667         outfile = NULL;
21668         multiple_files = 1;
21669         files = NULL;
21670         nb_files = 0;
21671         nb_libraries = 0;
21672         reloc_output = 0;
21673         print_search_dirs = 0;
21674     
21675         optind = parse_args(s, argc - 1, argv + 1) + 1;
21676     
21677         if (print_search_dirs) {
21678             /* enough for Linux kernel */
21679             printf("install: %s/\n", tcc_lib_path);
21680             return 0;
21681         }
21682     
21683         nb_objfiles = nb_files - nb_libraries;
21684     
21685         /* if outfile provided without other options, we output an
21686            executable */
21687         if (outfile && output_type == TCC_OUTPUT_MEMORY)
21688             output_type = TCC_OUTPUT_EXE;
21689     
21690         /* check -c consistency : only single file handled. XXX: checks file type */
21691         if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
21692             /* accepts only a single input file */
21693             if (nb_objfiles != 1)
21694                 error("cannot specify multiple files with -c");
21695             if (nb_libraries != 0)
21696                 error("cannot specify libraries with -c");
21697         }
21698         
21699         if (output_type != TCC_OUTPUT_MEMORY) {
21700             if (!outfile) {
21701         /* compute default outfile name */
21702                 pstrcpy(objfilename, sizeof(objfilename) - 1, 
21703                         /* strip path */
21704                         tcc_basename(files[0]));
21705     #ifdef TCC_TARGET_PE
21706                 pe_guess_outfile(objfilename, output_type);
21707     #else
21708                 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
21709                     char *ext = strrchr(objfilename, '.');
21710                 if (!ext)
21711                     goto default_outfile;
21712                     /* add .o extension */
21713                 strcpy(ext + 1, "o");
21714             } else {
21715             default_outfile:
21716                 pstrcpy(objfilename, sizeof(objfilename), "a.out");
21717             }
21718     #endif
21719             outfile = objfilename;
21720             }
21721         }
21722     
21723         if (do_bench) {
21724             start_time = getclock_us();
21725         }
21726     
21727         tcc_set_output_type(s, output_type);
21728     
21729         /* compile or add each files or library */
21730         for(i = 0;i < nb_files; i++) {
21731             const char *filename;
21732     
21733             filename = files[i];
21734             if (filename[0] == '-') {
21735                 if (tcc_add_library(s, filename + 2) < 0)
21736                     error("cannot find %s", filename);
21737             } else {
21738                 if (tcc_add_file(s, filename) < 0) {
21739                     ret = 1;
21740                     goto the_end;
21741                 }
21742             }
21743         }
21744     
21745         /* free all files */
21746         tcc_free(files);
21747     
21748         if (do_bench) {
21749             double total_time;
21750             total_time = (double)(getclock_us() - start_time) / 1000000.0;
21751             if (total_time < 0.001)
21752                 total_time = 0.001;
21753             if (total_bytes < 1)
21754                 total_bytes = 1;
21755             printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n", 
21756                    tok_ident - TOK_IDENT, total_lines, total_bytes,
21757                    total_time, (int)(total_lines / total_time), 
21758                    total_bytes / total_time / 1000000.0); 
21759         }
21760     
21761         if (s->output_type == TCC_OUTPUT_MEMORY) {
21762             ret = tcc_run(s, argc - optind, argv + optind);
21763         } else
21764     #ifdef TCC_TARGET_PE
21765         if (s->output_type != TCC_OUTPUT_OBJ) {
21766             ret = tcc_output_pe(s, outfile);
21767         } else
21768     #endif
21769         {
21770             tcc_output_file(s, outfile);
21771             ret = 0;
21772         }
21773      the_end:
21774         /* XXX: cannot do it with bound checking because of the malloc hooks */
21775         if (!do_bounds_check)
21776             tcc_delete(s);
21777     
21778     #ifdef MEM_DEBUG
21779         if (do_bench) {
21780             printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
21781         }
21782     #endif
21783         return ret;
21784     }
21785     
21786     // njn: created this wrapper main() function to execute compilation multiple
21787     // times.  TinyCC is fast!
21788     // Nb: we get a link error, and TinyCC would normally return non-zero.  But
21789     // the link error is not a problem for benchmarking purposes, so we return
21790     // zero here (as required by vg_perf).
21791     int main(int argc, char **argv)
21792     {
21793        #define REPS   30
21794        int i;
21795        for (i = 0; i < REPS; i++) {
21796           main2(argc, argv);
21797        }
21798        return 0;
21799     }
21800     
21801     #endif
21802     
21803     // njn: copied these in from libtcc1.c to avoid link errors when libtcc1.a
21804     // is not present.
21805     unsigned short __tcc_fpu_control = 0x137f;
21806     unsigned short __tcc_int_fpu_control = 0x137f | 0x0c00;
21807     
21808     #if 0
21809     long long __shldi3(long long a, int b)
21810     {
21811     #ifdef __TINYC__ 
21812         DWunion u;
21813         u.ll = a;
21814         if (b >= 32) {
21815             u.s.high = (unsigned)u.s.low << (b - 32);
21816             u.s.low = 0;
21817         } else if (b != 0) {
21818             u.s.high = ((unsigned)u.s.high << b) | (u.s.low >> (32 - b));
21819             u.s.low = (unsigned)u.s.low << b;
21820         }
21821         return u.ll;
21822     #else
21823         return a << b;
21824     #endif
21825     }
21826     #endif
21827